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

ReactBEGINNERMEDIUMUpdated Dec 10, 2025· 97 views

React issues this warning when the second argument to useEffect is an object (or any non-array value) instead of a dependency array.

Quick fix

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

useEffect(() => {
  fetchData();
}, { userId }); // ❌ object instead of array

useEffect(() => {
  console.log(props);
}, props); // ❌ passing props directly instead of [props]
  1. Locate the offending useEffect call
  2. Switch the second argument to an array
  3. Stabilize object dependencies before adding them
  4. Install and configure the React Hooks ESLint plugin
react — error
useEffect(() => {
fetchData();
}, { userId }); // ❌ object instead of array
useEffect(() => {
console.log(props);
}, props); // ❌ passing props directly instead of [props]
useEffect received a final argument of type `object` instead of an array

What this error means

React expects the last argument passed to useEffect to be an array of dependencies that control when the effect re-runs. When you pass an object (or any other non-array value) React cannot compare the dependencies between renders, so it throws this warning because the hook signature was violated. The mistake usually looks like passing configuration objects, props, or state values directly instead of wrapping them in square brackets. Even though objects are technically reference types in JavaScript, useEffect needs an array specifically so React can inspect each dependency with Object.is. Without that array, React cannot determine when to skip or re-run the effect, which can lead to inconsistent behavior or infinite loops in development builds.

Typical symptoms

  • Console warning that explicitly names the wrong type (object) instead of the dependency array
  • Effect runs on every render or stops respecting dependencies
  • Child components re-render more often than expected
  • TypeScript complains that object is not assignable to DependencyList
  • React DevTools highlights the component that has the bad useEffect call
  • Development build shows the warning repeatedly whenever the component renders
  • ESLint react-hooks/exhaustive-deps rule may still pass because lint only checks arrays

Common causes

  1. Passing an object literal / configuration object directly as the second argument to useEffect
  2. Mistaking useEffect's dependency array for setTimeout's delay argument and using curly braces
  3. Forgetting to wrap a single dependency value in brackets (e.g., using `useEffect(fn, props)`)
  4. Confusing the lint rule for exhaustive deps with the hook signature and omitting the array entirely
  5. Trying to reuse an object reference as a dependency without stabilizing it first
  6. Copy-pasting code that uses curly braces instead of square brackets for dependencies
  7. Passing React state setters or reducer dispatchers as the second argument
  8. Constructing the dependency list dynamically with helper functions that return objects instead of arrays

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

1Locate the offending useEffect call

Read the console warning to see which hook call triggered the message. The stack trace usually points to a component file and line number, and the warning text shows the value passed to useEffect.

Look for code such as:

javascript
useEffect(() => {
  fetchData();
}, { userId }); // ❌ object instead of array

useEffect(() => {
  console.log(props);
}, props); // ❌ passing props directly instead of [props]

Any non-array second argument is invalid and will trigger the warning.

2Switch the second argument to an array

Change the second argument to square brackets and list every value from the component scope that the effect relies on.

javascript
// ✔️ empty dependency array runs only once
useEffect(() => {
  sendAnalytics();
}, []);

// ✔️ array with dependencies
useEffect(() => {
  fetchData(userId);
}, [userId]);

// ✔️ multiple dependencies
useEffect(() => {
  updateChart(data, theme);
}, [data, theme]);

If you actually want the effect to run on every render, simply omit the second parameter entirely instead of passing an object.

3Stabilize object dependencies before adding them

Objects and arrays are reference types, so creating a new object inside render produces a new reference on every render even if the content does not change. Instead of listing the raw object as a dependency, either memoize it with the primitive values it depends on (useMemo with those primitives) or destructure those primitives directly and list them individually (for example, [filters.status, filters.sort]).

This keeps useEffect happy and avoids passing an object directly, because React compares each dependency with Object.is and will re-run the effect whenever a reference changes.

4Install and configure the React Hooks ESLint plugin

Add eslint-plugin-react-hooks if it is missing so you catch dependency array mistakes automatically.

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

In your ESLint config:

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

The exhaustive-deps rule enforces that the second argument is an array and that it lists the right values, preventing this warning before you even run the app.

5Verify the fix in the development build

Run the app locally and observe the console to make sure the warning disappears. Reload the component with the relevant props/state so the effect runs and confirm:

- The warning no longer appears.
- The effect only runs when listed dependencies change.
- Child components no longer re-render unnecessarily.

bash
npm run dev
# or
npm start

Use React DevTools to inspect renders if you still suspect unnecessary executions.

Advanced notes

How React compares dependencies: React uses Object.is internally to compare array entries between renders. That comparison only works when you provide an array. Passing an object bypasses this mechanism and leaves React guessing, which prompts the warning.

Avoid over-optimizing: Don't try to satisfy this warning by wrapping non-array values in helper functions that still return objects. The fix is always to use an array; if you need to depend on derived values, memoize them or break them into primitives before listing them as dependencies.

Frequently asked questions

What does "useEffect received a final argument of type `object` instead of an arr" mean?
React expects the last argument passed to useEffect to be an array of dependencies that control when the effect re-runs. When you pass an object (or any other non-array value) React cannot compare the dependencies between renders, so it throws this warning because the hook signature was violated. The mistake usually looks like passing configuration objects, props, or state values directly instead of wrapping them in square brackets.
How do I fix "useEffect received a final argument of type `object` instead of an arr"?
React issues this warning when the second argument to useEffect is an object (or any non-array value) instead of a dependency array.
What causes "useEffect received a final argument of type `object` instead of an arr"?
Passing an object literal / configuration object directly as the second argument to useEffect Mistaking useEffect's dependency array for setTimeout's delay argument and using curly braces Forgetting to wrap a single dependency value in brackets (e.g., using useEffect(fn, props))
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