React warns with this message when you pass an array of JSX elements (for example via props.children or an items prop) to another component without giving each element a stable key. React uses the keys to match up elements across renders, so the warning signals that the list you handed off lacks identity.
React builds its internal reconciliation tree when you hand a child component an array of nodes, so each element inside that array needs a key the moment you create it. The warning differs from "Each child in a list should have a unique key prop" only because the list is being passed to another component (via a prop or children) instead of being rendered in place. Even if the recipient component simply renders or clones `props.children`, the keys must already be set by the parent, otherwise React cannot tell which list item changed between renders. Use `React.Children.toArray` or inspect `child.key` if you need to replay the list, but the unique identifiers still belong on the elements themselves (for example a database `id`, slug, or other stable string).
Open the browser console and follow the stack trace. The warning usually points to a component whose props.children or items prop contains an array of JSX nodes. Look for patterns like:
const menuItems = products.map(product => (
<Item>{product.name}</Item> // no key yet
));
return <Menu options={menuItems} />;React warns because the array menuItems is being passed down without keys; the recipient component only renders what it gets, so the keys must exist before the list is passed along.
Give each mapped element a key that stays the same between renders. Prefer existing identifiers from your data instead of indexes:
const menuItems = products.map(product => (
<MenuOption key={product.id} value={product.value} />
));
return <Menu options={menuItems} />;If no natural ID exists, generate one when the data is created (uuid, crypto.randomUUID(), or a counter attached to the record) and store it on the item. Avoid keys based on Math.random() or index when the list can reorder, add, or remove elements, since React will reuse the wrong DOM nodes and the warning will return once the order changes.
If the component you pass the list to wraps, filters, or clones the children, do not drop their keys. Use React.Children.toArray or React.Children.map to access the original keys and forward them explicitly:
function Toolbar({ children }) {
return (
<nav>
{React.Children.map(children, (child) =>
React.cloneElement(child, { className: 'toolbar-item' })
)}
</nav>
);
}React.Children.map keeps the original keys, but if you manually wrap a child in another element, place the key on the wrapper level that you render or reuse the child's key before cloning. When you need to reorder or filter, React.Children.toArray(children) returns a flattened list with the keys React already assigns so you can inspect or re-map them without losing identity.
After keys are in place, refresh the app and reproduce the dynamic scenarios covered by the component:
# Open DevTools (F12) and clear the previous warning
# Add, remove, or reorder list entries
# Check the console for the missing-key warning
# Interact with inputs inside the list to ensure focus/state survivesIf the warning persists, double-check that the key lives on the element returned directly from the .map (not on a child element inside a mapped component) and that no wrapper strips the original key.
Keys are central to React's reconciliation algorithm; React tracks each sibling based on the key, not the index or the component type alone. When keys change, React unmounts the old component and mounts a new one, which is why the warning often accompanies unexpected state loss or focus jumps. This warning can also surface during server-side rendering/hydration if the server and client build the same list without keys, so keep your data sources consistent between server and client renders.
If you must filter or sort props.children, prefer React.Children.toArray(children) before the operation so React keeps track of the keys it already assigned. The ESLint rule react/jsx-key can catch missing keys at lint time and is especially helpful when you build arrays outside of the JSX expression. For long lists, consider virtualization libraries (react-window, react-virtuoso) and keep keys stable to prevent excessive re-renders even with pagination or infinite scroll.
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