How to fix Warning: useEffect received a final argument that is not an array (instead, received `[type]`). When specified, the final argument must be an array. in React

ReactBEGINNERMEDIUMUpdated Dec 8, 2025ยท 115 views

React displays a warning when useEffect receives a second argument that is not an array. The second parameter must be an array of dependencies or omitted entirely.

Quick fix

Fixes Warning: useEffect received a final argument that is not an array (instead, received `[type]`). When specified, the final argument must be an array.

// Wrong - passing a number
useEffect(() => {
  console.log('Effect runs');
}, 0);

// Wrong - passing a boolean
useEffect(() => {
  fetchData();
}, true);

// Wrong - passing single value without array
useEffect(() => {
  updateTitle();
}, count);
  1. Identify the problematic useEffect call
  2. Replace the second argument with an array
  3. Add all dependencies used inside the effect
  4. Enable ESLint exhaustive-deps rule
react โ€” error
// Wrong - passing a number
useEffect(() => {
console.log('Effect runs');
}, 0);
// Wrong - passing a boolean
useEffect(() => {
fetchData();
}, true);
// Wrong - passing single value without array
useEffect(() => {
updateTitle();
}, count);
Warning: useEffect received a final argument that is not an array (instead, received `[type]`). When specified, the final argument must be an array.

What this error means

This warning occurs when you pass a non-array value as the second parameter to the useEffect Hook. React's useEffect accepts an optional dependency array as its second argument to control when the effect runs. If you provide this argument, it must be an array containing the dependencies your effect relies on. React compares the values in this array between renders to determine if the effect should re-run. Passing any other type (like a number, boolean, string, object, or undefined) causes this warning because React cannot perform the dependency comparison it needs. The warning message specifically tells you what type you accidentally passed instead of an array, making it easier to identify where the mistake occurred in your code.

Typical symptoms

  • Console warning: "useEffect received a final argument that is not an array"
  • Warning message shows the actual type received (e.g., "received `boolean`" or "received `number`")
  • Effect may run on every render instead of only when dependencies change
  • Application still functions but with suboptimal performance
  • React development build displays the warning in browser console
  • ESLint or TypeScript may show type errors if using strict type checking
  • Effect behavior is unpredictable when wrong argument type is passed

Common causes

  1. Passing a number as the second argument, often mistaking it for a timeout value
  2. Passing a boolean value, attempting to conditionally control effect execution
  3. Passing a single dependency without wrapping it in an array
  4. Passing an object or function directly instead of inside an array
  5. Accidentally passing null or undefined when intending to pass an empty array
  6. Typo or syntax error that results in evaluating to a non-array value
  7. Confusion between useEffect syntax and setTimeout/setInterval syntax
  8. Copying code from older React patterns or incorrect examples

How to fix "Warning: useEffect received a final argument that is not an array (instead, received `[type]`). When specified, the final argument must be an array."

1Identify the problematic useEffect call

Check your console warning to see which component and line contains the error. The warning will tell you what type was received instead of an array.

Look for useEffect calls in your component:

javascript
// Wrong - passing a number
useEffect(() => {
  console.log('Effect runs');
}, 0);

// Wrong - passing a boolean
useEffect(() => {
  fetchData();
}, true);

// Wrong - passing single value without array
useEffect(() => {
  updateTitle();
}, count);
2Replace the second argument with an array

Wrap your dependency in square brackets to create an array. If you have no dependencies, use an empty array. If you want the effect to run on every render, omit the second argument entirely.

javascript
// Correct - empty array (runs once on mount)
useEffect(() => {
  console.log('Effect runs once');
}, []);

// Correct - single dependency in array
useEffect(() => {
  updateTitle();
}, [count]);

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

// Correct - no second argument (runs on every render)
useEffect(() => {
  console.log('Runs on every render');
});
3Add all dependencies used inside the effect

Ensure any variable, prop, or state used inside your effect is included in the dependency array. This is critical for correct behavior.

javascript
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState('light');

  // Include ALL variables used inside the effect
  useEffect(() => {
    fetchUser(userId).then(data => {
      setUser(data);
      applyTheme(theme);
    });
  }, [userId, theme]); // Both userId and theme must be listed

  return <div>{user?.name}</div>;
}
4Enable ESLint exhaustive-deps rule

Use the eslint-plugin-react-hooks to automatically catch missing or incorrect dependencies. This plugin will warn you about dependency array issues.

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 any dependency array problems in your editor.

5Handle object and array dependencies properly

Objects and arrays are compared by reference in JavaScript, which can cause effects to re-run unnecessarily. Use useMemo or useCallback to stabilize these values.

javascript
function SearchComponent({ config }) {
  const [results, setResults] = useState([]);

  // Wrong - config object changes reference every render
  useEffect(() => {
    search(config).then(setResults);
  }, [config]); // This will run on every render

  // Better - memoize the config object
  const memoizedConfig = useMemo(() => config, [
    config.query,
    config.limit,
    config.filters
  ]);

  useEffect(() => {
    search(memoizedConfig).then(setResults);
  }, [memoizedConfig]);

  // Or extract primitive values
  const { query, limit } = config;
  useEffect(() => {
    search({ query, limit }).then(setResults);
  }, [query, limit]); // Use primitives directly
}
6Verify the fix in development mode

Run your application in development mode and check that the warning no longer appears in the console. Test the component behavior to ensure effects run at the correct times.

bash
npm run dev
# or
npm start

Navigate to the affected component and verify:
- No console warnings appear
- Effect runs when dependencies change
- Effect doesn't run unnecessarily
- Application behavior is correct

7Review all useEffect calls in the codebase

Search for other instances of useEffect to ensure consistent correct usage across your project.

bash
# Search for useEffect usage
grep -r "useEffect" src/

# Use your IDE's search to find all occurrences

Look for patterns like:
- useEffect with no second argument when dependencies should be specified
- useEffect with empty array when dependencies are actually needed
- Any remaining non-array second arguments

Advanced notes

Understanding Dependency Comparison: React uses Object.is() for comparing dependency values between renders. This means primitive values (numbers, strings, booleans) are compared by value, while objects and arrays are compared by reference. Two objects with identical contents but different references are considered different.

Empty Array vs. No Array: An empty dependency array [] means the effect runs once after the initial render (component mount). Omitting the array entirely means the effect runs after every render. Choose based on your specific needs.

React 18 Strict Mode: In React 18's Strict Mode during development, effects run twice to help identify side effects and bugs. This is intentional and only happens in development mode, not production.

Custom Hooks and Dependencies: When creating custom hooks that use useEffect internally, ensure you document what dependencies the hook expects and properly pass them through from the consuming component.

Performance Considerations: While it might be tempting to pass an empty array to avoid re-running effects, this can lead to stale closures where your effect uses outdated values. Always include actual dependencies to ensure correct behavior, and use memoization techniques if performance becomes a concern.

TypeScript Integration: If using TypeScript, the dependency array is typed as DependencyList | undefined, which is defined as ReadonlyArray<any> | undefined. This type constraint helps catch non-array arguments at compile time.

Frequently asked questions

What does "Warning: useEffect received a final argument that is not an array (ins" mean?
This warning occurs when you pass a non-array value as the second parameter to the useEffect Hook. React's useEffect accepts an optional dependency array as its second argument to control when the effect runs. If you provide this argument, it must be an array containing the dependencies your effect relies on.
How do I fix "Warning: useEffect received a final argument that is not an array (ins"?
React displays a warning when useEffect receives a second argument that is not an array. The second parameter must be an array of dependencies or omitted entirely.
What causes "Warning: useEffect received a final argument that is not an array (ins"?
Passing a number as the second argument, often mistaking it for a timeout value Passing a boolean value, attempting to conditionally control effect execution Passing a single dependency without wrapping it in an array
Is the "Warning: useEffect received a final argument that is not an array (ins" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading