This warning occurs when a props object containing a "key" property is spread into JSX. React requires keys to be passed directly to JSX elements, not through spread operators, to properly track components during rendering.
This warning appears when you attempt to spread a props object that includes a "key" property into a JSX element. React treats "key" and "ref" as special props that are reserved for React's internal reconciliation algorithm. These props are not forwarded to components like regular props. When you use the spread operator (...props) with an object containing a key property, React cannot properly extract and use the key for its reconciliation process. The key prop must be explicitly declared on the JSX element itself, separate from any spread operations. This warning became more prominent and strictly enforced in React 18.3.0 and later versions. While the code may still function, ignoring this warning can lead to unpredictable behavior in list rendering and component updates, as React relies on keys to efficiently identify which items have changed, been added, or removed.
Destructure your props object to separate the key from other properties:
// ❌ Wrong - spreading object with key
const props = { key: item.id, name: item.name, value: item.value };
<Component {...props} />
// ✅ Correct - extract key before spreading
const props = { key: item.id, name: item.name, value: item.value };
const { key, ...restProps } = props;
<Component key={key} {...restProps} />This ensures React receives the key as a direct JSX attribute while other props are spread normally.
When mapping over arrays, always pass the key directly to the JSX element, not through spread:
// ❌ Wrong
const items = data.map(item => {
const props = { key: item.id, ...item };
return <ListItem {...props} />;
});
// ✅ Correct
const items = data.map(item => (
<ListItem key={item.id} name={item.name} value={item.value} />
));If you need the key value as a prop, pass it with a different name like id or itemKey.
If you have wrapper components that forward props, modify them to extract and handle key explicitly:
// ❌ Wrong wrapper
function Wrapper(props) {
return <div><Component {...props} /></div>;
}
// ✅ Correct wrapper
function Wrapper({ key, ...restProps }) {
return <div><Component key={key} {...restProps} /></div>;
}
// Or if the wrapper itself needs the key:
function Wrapper(props) {
const { key: itemKey, ...restProps } = props;
return <div key={itemKey}><Component {...restProps} /></div>;
}If you use helper functions to merge or construct props objects, ensure they don't include key in the merged result:
// ❌ Wrong - includes key in merged props
const mergeProps = (defaults, overrides) => ({ ...defaults, ...overrides });
const props = mergeProps({ color: "blue" }, { key: id, color: "red" });
<Component {...props} />
// ✅ Correct - extract key after merging
const mergeProps = (defaults, overrides) => {
const merged = { ...defaults, ...overrides };
const { key, ...rest } = merged;
return { key, props: rest };
};
const { key, props } = mergeProps({ color: "blue" }, { key: id, color: "red" });
<Component key={key} {...props} />If using UI libraries like Material-UI, React Native Paper, or PrimeReact, ensure you're using the latest version that addresses this warning:
npm update @mui/material
# or
npm update react-native-paper
# or
npm update primereactMany libraries released patches in response to React 18.3.0's stricter enforcement. Check the library's GitHub issues for specific guidance on handling this warning with their components.
Add or ensure the react/jsx-key ESLint rule is enabled in your .eslintrc configuration:
{
"rules": {
"react/jsx-key": ["error", {
"checkFragmentShorthand": true,
"checkKeyMustBeforeSpread": true,
"warnOnDuplicates": true
}]
}
}The checkKeyMustBeforeSpread option specifically catches cases where key is included in spread props.
After making changes, clear your console and reload your application:
# Clear dev server cache if needed
rm -rf .next # for Next.js
rm -rf node_modules/.cache # for Create React App
npm run devMonitor the console to confirm the "A props object containing a 'key' prop is being spread into JSX" warning no longer appears during list rendering or component mounting.
The key prop is one of two "special" props in React (along with ref) that are reserved for React's internal use and are never passed to components as props. This is by design: keys are used by React's reconciliation algorithm to identify which items in a list have changed, been added, or been removed, enabling efficient updates to the DOM.
If you genuinely need to access the key value inside your component, you must pass it as a separate prop with a different name (commonly "id", "itemKey", or "itemId"). For example: <Item key={item.id} id={item.id} /> where key is used by React internally and id is accessible within the Item component.
In TypeScript projects, you may encounter type errors when trying to destructure key from props. The React types intentionally exclude key from component prop types. Use type assertions carefully if you must work with objects containing keys before rendering.
Some component patterns like render props or HOCs may require special handling. If you're building a HOC that wraps components in lists, document clearly that consumers must pass key to the HOC instance, not to the wrapped component.
Performance note: While spreading props is convenient, it can lead to unnecessary re-renders if not used carefully. Consider using React.memo() or useMemo() for components that receive frequently-changing props through spread operators.
For React Native developers: This warning appears with the same frequency in React Native 0.74+ due to the shared React 18.3.0 core. The fixes are identical to web React applications.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite