How to fix useEffect received a final argument of type `object` instead of an array in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025ยท 87 views

This error occurs when you pass an object as the second argument to React's useEffect hook instead of an array of dependencies. The useEffect hook expects its dependencies to be in an array format for proper comparison between renders. This mistake often leads to infinite re-renders or the effect not running when expected.

Quick fix

Fixes useEffect received a final argument of type `object` instead of an array

// Wrong - passing an object directly
useEffect(() => {
  fetchData();
}, { userId, limit }); // Object instead of array

// Wrong - object literal without array
useEffect(() => {
  updateTitle();
}, config); // config is an object

// Wrong - using curly braces instead of square brackets
useEffect(() => {
  console.log('Effect runs');
}, { userId }); // Curly braces create object
  1. Identify the problematic useEffect call
  2. Wrap dependencies in an array
  3. Memoize objects with useMemo when needed
  4. Use primitive values instead of objects
react โ€” error
// Wrong - passing an object directly
useEffect(() => {
fetchData();
}, { userId, limit }); // Object instead of array
// Wrong - object literal without array
useEffect(() => {
updateTitle();
}, config); // config is an object
// Wrong - using curly braces instead of square brackets
useEffect(() => {
console.log('Effect runs');
}, { userId }); // Curly braces create object
useEffect received a final argument of type `object` instead of an array

What this error means

The useEffect hook in React is designed to run side effects after render. Its second parameter is a dependency array that tells React when to re-run the effect based on changes to the listed values. When you accidentally pass an object instead of an array, React can't properly track dependencies, leading to unexpected behavior. React compares dependency values using Object.is() for equality checking. When you pass an object as the second argument, React sees it as a single dependency that changes reference on every render (since objects are compared by reference, not by value). This causes the effect to run on every render, potentially creating infinite loops or performance issues. The error message specifically mentions receiving an "object" type, but this warning can also appear for other non-array types like numbers, booleans, or strings passed as the second argument.

Typical symptoms

  • Console warning: "useEffect received a final argument of type `object` instead of an array"
  • Effect runs on every render regardless of dependency changes
  • Infinite re-render loops in your component
  • ESLint warnings about missing or incorrect dependencies
  • The effect doesn't run when expected dependencies change
  • Performance degradation due to unnecessary effect executions
  • React development build displays the warning in browser console

Common causes

  1. Passing an object literal directly in the dependency position without wrapping it in an array
  2. Forgetting to wrap dependencies in square brackets
  3. Using object destructuring incorrectly in the dependency array
  4. Confusing the useEffect signature with other hooks like useMemo or useCallback
  5. Copying code from examples that use objects for configuration
  6. Attempting to pass configuration options as an object instead of using the dependency array
  7. Syntax error where curly braces are used instead of square brackets

How to fix "useEffect received a final argument of type `object` instead of an array"

1Identify the problematic useEffect call

Check your console warning to see which component contains the error. Look for useEffect calls where the second argument might be an object.

javascript
// Wrong - passing an object directly
useEffect(() => {
  fetchData();
}, { userId, limit }); // Object instead of array

// Wrong - object literal without array
useEffect(() => {
  updateTitle();
}, config); // config is an object

// Wrong - using curly braces instead of square brackets
useEffect(() => {
  console.log('Effect runs');
}, { userId }); // Curly braces create object
2Wrap dependencies in an array

Replace the object with an array containing the dependencies. If you have multiple dependencies, list them inside the array.

javascript
// Correct - single dependency in array
useEffect(() => {
  fetchData();
}, [userId]);

// Correct - multiple dependencies in array
useEffect(() => {
  updateTitle();
}, [userId, limit]);

// Correct - empty array for no dependencies
useEffect(() => {
  initialize();
}, []);

// Correct - object properties as separate dependencies
useEffect(() => {
  fetchData();
}, [config.userId, config.limit]); // Extract properties
3Memoize objects with useMemo when needed

If you need to use an object as a dependency (for example, configuration objects), memoize it with useMemo to maintain referential equality.

javascript
function UserComponent({ userId, settings }) {
  // Memoize the config object
  const config = useMemo(() => ({
    userId,
    limit: settings.limit,
    sortBy: settings.sortBy
  }), [userId, settings.limit, settings.sortBy]);

  // Now config can be used as a dependency
  useEffect(() => {
    fetchUserData(config);
  }, [config]); // config reference is stable when dependencies don't change

  return <div>User data</div>;
}
4Use primitive values instead of objects

Whenever possible, use individual primitive values in the dependency array rather than entire objects. This is more predictable and avoids reference comparison issues.

javascript
// Instead of passing the entire config object:
useEffect(() => {
  fetchData(config);
}, [config]); // Object reference changes on every render

// Pass the specific primitive values needed:
useEffect(() => {
  fetchData({ userId, limit });
}, [userId, limit]); // Primitives compared by value

// Or extract properties from the object:
const { userId, limit } = config;
useEffect(() => {
  fetchData({ userId, limit });
}, [userId, limit]);
5Enable ESLint exhaustive-deps rule

Use eslint-plugin-react-hooks to automatically catch dependency array issues. This plugin will warn you about incorrect dependency specifications.

Install the plugin if not already present:

bash
npm install eslint-plugin-react-hooks --save-dev

Add to your .eslintrc configuration:

json
{
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

The exhaustive-deps rule will highlight dependency array problems in your editor, including when you pass non-array values.

6Test the fix in development mode

Run your application in development mode and verify the warning no longer appears. Test that effects run at the correct times.

bash
npm run dev
# or
npm start

Navigate to the affected component and check:
- No console warnings about useEffect arguments
- Effect runs when dependencies actually change
- Effect doesn't run unnecessarily
- Application behavior is correct

Advanced notes

Reference Equality vs. Value Equality: React uses Object.is() for dependency comparison, which means objects and arrays are compared by reference, not by content. Two objects with identical properties are considered different if they have different references. This is why passing new object literals causes effects to re-run.

Empty Array vs. No Array: An empty dependency array [] means the effect runs once after initial mount. Omitting the array entirely means the effect runs after every render. Passing an object (or any non-array) is invalid and triggers this warning.

React 18 Strict Mode: In React 18's Strict Mode during development, effects run twice to help identify side effects. This is normal and helps catch bugs early.

Custom Comparison Hooks: For complex cases where you need deep object comparison, consider libraries like react-use's useDeepCompareEffect or implementing custom comparison logic with useRef and useEffect.

TypeScript Support: TypeScript can help catch this error at compile time by enforcing the correct type for the second argument (DependencyList | undefined).

Frequently asked questions

What does "useEffect received a final argument of type `object` instead of an arr" mean?
The useEffect hook in React is designed to run side effects after render. Its second parameter is a dependency array that tells React when to re-run the effect based on changes to the listed values. When you accidentally pass an object instead of an array, React can't properly track dependencies, leading to unexpected behavior.
How do I fix "useEffect received a final argument of type `object` instead of an arr"?
This error occurs when you pass an object as the second argument to React's useEffect hook instead of an array of dependencies. The useEffect hook expects its dependencies to be in an array format for proper comparison between renders. This mistake often leads to infinite re-renders or the effect not running when expected.
What causes "useEffect received a final argument of type `object` instead of an arr"?
Passing an object literal directly in the dependency position without wrapping it in an array Forgetting to wrap dependencies in square brackets Using object destructuring incorrectly in the dependency array
Is the "useEffect received a final argument of type `object` instead of an arr" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading