How to fix useMemo received a final argument of type `object` instead of in React
This error occurs when useMemo receives a second argument that is not an array, or when the dependency array format is invalid. The dependencies parameter must be passed as an array literal to properly track reactive values.
Quick fix
Fixes useMemo received a final argument of type `object` instead of
// ✅ Correct - dependency array with square brackets
const memoizedValue = useMemo(() => expensiveCalculation(a, b), [a, b]);
// ❌ Wrong - object literal with curly braces
const memoizedValue = useMemo(() => expensiveCalculation(a, b), {a, b});
// ❌ Wrong - parentheses instead of brackets
const memoizedValue = useMemo(() => expensiveCalculation(a, b), (a, b));
// ❌ Wrong - missing array wrapper
const memoizedValue = useMemo(() => expensiveCalculation(a, b), a, b);- Verify the useMemo syntax structure
- Check for missing or extra commas
- Ensure dependency array is a literal array
- Include all reactive values as dependencies
// ✅ Correct - dependency array with square bracketsconst memoizedValue = useMemo(() => expensiveCalculation(a, b), [a, b]);// ❌ Wrong - object literal with curly bracesconst memoizedValue = useMemo(() => expensiveCalculation(a, b), {a, b});// ❌ Wrong - parentheses instead of bracketsconst memoizedValue = useMemo(() => expensiveCalculation(a, b), (a, b));// ❌ Wrong - missing array wrapperconst memoizedValue = useMemo(() => expensiveCalculation(a, b), a, b);useMemo received a final argument of type `object` instead of
What this error means
This error indicates that the second argument passed to React's useMemo hook is not in the expected array format. The useMemo hook expects two arguments: a calculation function and a dependency array. The dependency array tells React when to recalculate the memoized value by tracking reactive values like props, state, and local variables. When you pass something other than an array as the second argument (such as an object, function, or omit it entirely with incorrect syntax), React cannot properly track dependencies and throws this error. The error message specifically mentions receiving an "object" type instead of the expected array, which typically happens when curly braces are used instead of square brackets, or when the dependency argument is malformed. React's static analysis and ESLint plugins rely on the dependency array being a literal array to verify that all reactive values are correctly specified as dependencies. Without a proper array format, these tools cannot perform their checks, leading to potential bugs where memoization doesn't work as expected.
Typical symptoms
- Error message "useMemo received a final argument of type `object` instead of" in console
- Component renders fail or component behavior is unpredictable
- Memoization does not work and expensive calculations run on every render
- ESLint warnings about useMemo dependency array not being verifiable
- TypeScript compilation errors related to useMemo argument types
- React DevTools shows unexpected re-renders despite using useMemo
- Application crashes during development with dependency-related errors
Common causes
- Passing an object literal with curly braces {} instead of array brackets [] as the second argument
- Omitting the dependency array entirely and accidentally passing another value
- Using parentheses () instead of square brackets [] for the dependency array
- Passing a function or variable that evaluates to a non-array as the second argument
- Syntax error where the dependency array is not properly closed or formatted
- Passing computed/dynamic values directly instead of wrapping them in an array
- Confusion between useMemo and useEffect syntax patterns
- Incorrect destructuring or spreading of dependency values outside the array
How to fix "useMemo received a final argument of type `object` instead of"
Check that your useMemo call follows the correct format with square brackets for the dependency array:
// ✅ Correct - dependency array with square brackets
const memoizedValue = useMemo(() => expensiveCalculation(a, b), [a, b]);
// ❌ Wrong - object literal with curly braces
const memoizedValue = useMemo(() => expensiveCalculation(a, b), {a, b});
// ❌ Wrong - parentheses instead of brackets
const memoizedValue = useMemo(() => expensiveCalculation(a, b), (a, b));
// ❌ Wrong - missing array wrapper
const memoizedValue = useMemo(() => expensiveCalculation(a, b), a, b);Ensure you're using square brackets [] to wrap all dependencies.
Verify that the syntax between the calculation function and dependency array is correct:
// ✅ Correct - comma between function and array
const value = useMemo(() => {
return expensive(data);
}, [data]);
// ❌ Wrong - missing comma
const value = useMemo(() => {
return expensive(data);
} [data]);
// ❌ Wrong - extra comma creating unexpected behavior
const value = useMemo(() => expensive(data),, [data]);The comma separating the two arguments is essential for proper parsing.
React's linter and static analysis require the dependency array to be defined inline as a literal:
// ✅ Correct - inline array literal
const result = useMemo(() => compute(x, y), [x, y]);
// ⚠️ Discouraged - variable reference (can't be statically verified)
const deps = [x, y];
const result = useMemo(() => compute(x, y), deps);
// ❌ Wrong - object passed as second argument
const config = { dependencies: [x, y] };
const result = useMemo(() => compute(x, y), config);Always define the array directly in the useMemo call for proper linting support.
List every variable, prop, or state value used inside the calculation function:
function MyComponent({ data, filter }) {
const [sortOrder, setSortOrder] = useState('asc');
// ✅ Correct - all reactive values included
const sortedData = useMemo(() => {
return data
.filter(item => item.type === filter)
.sort((a, b) => sortOrder === 'asc' ? a.value - b.value : b.value - a.value);
}, [data, filter, sortOrder]);
// ❌ Wrong - missing dependencies
const sortedData = useMemo(() => {
return data.filter(item => item.type === filter).sort(...);
}, [data]); // Missing: filter, sortOrder
}Enable the eslint-plugin-react-hooks to catch missing dependencies automatically.
When dependencies are objects or arrays, ensure they have stable references:
function MyComponent({ config }) {
// ❌ Wrong - new object created on every render
const result = useMemo(() => {
return process(config);
}, [{ setting: config.setting }]); // New object reference each time
// ✅ Better - depend on primitive values
const result = useMemo(() => {
return process(config);
}, [config.setting, config.option]);
// ✅ Best - if you must pass whole object, memoize it first
const memoizedConfig = useMemo(() => ({
setting: config.setting,
option: config.option
}), [config.setting, config.option]);
const result = useMemo(() => {
return process(memoizedConfig);
}, [memoizedConfig]);
}Avoid creating new object/array literals inside the dependency array.
If the calculation should only run once and has no dependencies, use an empty array:
// ✅ Correct - empty array for one-time calculation
const initialData = useMemo(() => {
return generateExpensiveData();
}, []);
// ❌ Wrong - omitting the array entirely (runs every render)
const initialData = useMemo(() => {
return generateExpensiveData();
});
// ⚠️ Note: For truly constant data, consider useState with initializer instead
const [initialData] = useState(() => generateExpensiveData());An empty dependency array means the calculation runs only on mount.
If using TypeScript, ensure your dependency array typing is correct:
import { useMemo } from 'react';
interface Props {
items: string[];
multiplier: number;
}
function MyComponent({ items, multiplier }: Props) {
// ✅ Correct - TypeScript can infer the dependency array type
const processed = useMemo(() => {
return items.map(item => item.length * multiplier);
}, [items, multiplier]);
// ❌ Wrong - trying to type the dependency parameter
const processed = useMemo(() => {
return items.map(item => item.length * multiplier);
}, [items, multiplier] as [string[], number]); // Unnecessary and can cause issues
}TypeScript automatically validates dependency array types when using proper syntax.
Advanced notes
Common Pattern Confusion: Developers sometimes confuse useMemo with useEffect syntax. While both accept dependency arrays, useEffect doesn't return a value and useMemo is synchronous. The useMemo hook must always return a value from its calculation function.
ESLint Configuration: Install and configure eslint-plugin-react-hooks to catch dependency issues automatically. Add to your ESLint config:
{
"plugins": ["react-hooks"],
"rules": {
"react-hooks/exhaustive-deps": "warn"
}
}Performance Consideration: useMemo adds overhead. Only use it for expensive calculations or when passing object/array references to child components that might trigger unnecessary re-renders. Don't memoize everything by default.
Dependency Array Size Changes: Another related warning is "The final argument passed to useMemo changed size between renders." This occurs when the dependency array length changes dynamically, which React doesn't allow. The array must have a constant size and order. If you need variable dependencies, restructure your component logic.
React Compiler: Future versions of React may include a compiler that automatically handles memoization, potentially making manual useMemo usage less common. However, understanding proper dependency management remains crucial for React development.
Frequently asked questions
- What does "useMemo received a final argument of type `object` instead of" mean?
- This error indicates that the second argument passed to React's useMemo hook is not in the expected array format. The useMemo hook expects two arguments: a calculation function and a dependency array. The dependency array tells React when to recalculate the memoized value by tracking reactive values like props, state, and local variables.
- How do I fix "useMemo received a final argument of type `object` instead of"?
- This error occurs when useMemo receives a second argument that is not an array, or when the dependency array format is invalid. The dependencies parameter must be passed as an array literal to properly track reactive values.
- What causes "useMemo received a final argument of type `object` instead of"?
- Passing an object literal with curly braces {} instead of array brackets [] as the second argument Omitting the dependency array entirely and accidentally passing another value Using parentheses () instead of square brackets [] for the dependency array
- Is the "useMemo received a final argument of type `object` instead of" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚React Official Documentation
- 📖Official: React useMemo Reference(Official Docs)
- 💬GitHub: useMemo changed size between renders(Stack Overflow)
- 📖Official: React Hooks API Reference(Official Docs)
- 💬GitHub: react-hooks/exhaustive-deps discussion(Stack Overflow)