material-ui
material-ui copied to clipboard
React "each child in a list should have a unique key" error when bundling MUI
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
bundling mui in production mode generates key errors for seemingly no reason
Expected behavior 🤔
bundling mui in production mode does not generate key errors for components that arent actually part of a list
Steps to reproduce 🕹
Steps:
- To reproduce the error, clone this minimal reproduction to your local machine and then npm ci to load the dependencies.
- Next, run
npm run build:prodto create a production bundle - Use npm link to run the library against a fresh React app via Create-react-app or something similar.
- Within your fresh React application, just import the Tooltip and/or Checkbox components from this library while linked and then render them to the page. You will see the react errors.
- While linked, you can then run
npm run build:devto generate a development build. The Tooltip and Checkbox in you React app should no longer throw the unique key errors in the console.
Context 🔦
my team manages an internal component library that is based on mui and gets consumed by all other frontend developers at my job. This component library imports MUI components/helpers and makes any modifications needed, and then exports all of the modified stuff as well as all of the unmodified MUI functions (think export * from @mui/material basically).
What we've been doing is bundling mui into our component library at build time, that way consuming applications just install our component library, rather than having to install our component library + a bunch of MUI peer dependencies. However, we noticed that when we publish the production build of our component library, certain components such as the Tooltip and Checkbox will throw "each child in a list should have a unique key" warnings once they're imported and used in our applications.
Initially we thought this was an issue with our custom components or maybe our build chain, but I was able to recreate the problem by just making a brand new npm package, importing and then re-exporting all the MUI stuff and building the npm package in production mode. I then used npm link to run the package in a fresh Create React App and the Checkbox + Tooltip components immediately threw the key warnings.

Is this intended behavior and/or is this documented anywhere? Are we just supposed to build a development bundle instead? Ultimately our goal is to be able to bundle mui into our company's internal component library so that the component library maintainers can control the version of things and consumers can simply rely on importing our package
Your environment 🌎
npx @mui/envinfo
Unfortunately the npx @mui/envinfo command doesnt seem to be working for me?? I attempt to execute it and it just hangs on the CLI. I am using Node 14 on macOs monterrey

Any progress on this? Experiencing the same issue.
We're also experiencing this issue.. has there been any progress?
I am not able to reproduce your issue. Instead I am getting the following error in my React application after linking @company/components to my React app with npm link:
Uncaught TypeError: Cannot set properties of undefined (setting 'runtime')
Code:
import {Tooltip, Button} from '@company/components'
function App() {
return (
<Tooltip>
<Button>
abc
</Button>
</Tooltip>
);
}
export default App;
Im not totally sure what changed with CRA since initially opening this issue, but since CRA doesn't seem to offer any way to run an older version I just created a barebones react-app from scratch that can be used for npm link to work. The barebones react app can be cloned from https://github.com/lancej1022/bare-react
Ive also updated the MUI POC for the issue so that the webpack config can output to UMD rather than ESM if you just change some of the commented code (notes are within webpack.config.cjs) https://github.com/lancej1022/mui-poc
The repro steps for the issue should now look like:
- To reproduce the error, clone this minimal reproduction to your local machine and then
npm cito load the dependencies. - Next, run
npm run build:prodto create a production bundle - Use
npm linkto run the library against the barebones react app - Within your fresh React application, run
npm startsince the relevant components should already be imported withinApp.js. You will see the react errors aboutkeys. - While linked, you can then run
npm run build:devwithin the mui-poc repo to generate a development build. The Tooltip and Checkbox in your React app will no longer throw the unique key errors in the console.
@lancej1022 If there is no key error in the UMD development build but rather in the ESM bundle, is this an issue with Webpack?
@lancej1022 If there is no
keyerror in the UMD development build but rather in the ESM bundle, is this an issue with Webpack?
I think my previous message may have been confusing. To be clear, the key error is present in both UMD and ESM builds. I simply made it easy to switch between ESM/UMD within the reproduction so that whoever investigates this issue can see that the issue is not related to webpack's build target (as far as I can tell)
Just wanted to check in and see if the MUI team has any sort of recommendation for solving/avoiding this? I was under the impression that building a component library on top of MUI was pretty common but I haven't been able to find any documentation around proper bundling of MUI in the 4 months since this issue has been open. The only way I can think of to get around this issue would be to not bundle MUI at all and mark it as a peerDependency instead
@lancej1022 I can reproduce the error now. But unfortunately, I am not able to find a solution or workaround for this.
Could this be reated to https://github.com/facebook/react/issues/11537?
@lancej1022 I can reproduce the error now. But unfortunately, I am not able to find a solution or workaround for this.
Could this be reated to facebook/react#11537?
Potentially? Im not overly familiar with babel transforms, but the babel config in the sample react app I provided is relatively simple so Im not sure if it is the issue. I was also thinking the issue might be with Emotion itself, but Im not familiar with how MUI + emotion work together internally.
The same warning appears using FocusTrap. I believe the issue originates at:

Although it is not an ideal solution since a list is not being rendered, passing in a key eliminates the warning for all instances of the FocusTrap:
{
{React.cloneElement(children, { ref: handleRef, onFocus, key:"some-key" })}
}
This could be the same issue with Tooltip which uses React clone element:

Sorry, I can't offer a solution, but I hope this is helpful.
I am experiencing the same two warnings when using Tooltip and a nested FocusTrap within a custom components library based on MUI. I am hopeful that the team can find a solution to these warnings soon. I will continue to follow the discussion for any updates or resolutions.
We have the same issue with Tooltip and FocusTrap.
I'll take a look into this issue
Thanks @lancej1022 for the useful reproduction and easy-to-follow steps, it was really helpful. Also thanks @Coreen-Cooper for finding out that cloneElement was the origin.
The issue can be solved by modifying the webpack config like this:
-const externals = {};
-Object.keys(pkg.peerDependencies).forEach((dep) => {
- externals[dep] = dep;
-});
+const externals = new RegExp(
+ `^(?:${Object.keys(pkg.peerDependencies).join("|")})(?:/.*)?$`
+);
After this change, the externals config becomes /^(?:date-fns|react|react-dom)(?:\/.*)?$/. As you can see, the peer dependencies subpaths are also included in the externals, as they should. In particular react/jsx-runtime was the one that was missing, so it was being bundled even though it shouldn't.
You can check the difference this config change makes in this diff check: https://www.diffchecker.com/A143le9a/
I haven't dug deep enough to understand why this caused cloneElement to throw the error. The bottom line is React doesn't work properly when multiple versions of it or one of its dependencies are loaded simultaneusly.
As this is an issue various people stumbled upon, before closing it I will come up with some further actions to try to avoid it in the future and will post those here when I have them.
Building a component library on top of Material UI seems to be a common user case, so to avoid configuration errors that might lead to frustration, I've opened the following RFC: https://github.com/mui/material-ui/issues/37952. The action point is adding a starting point and guidance for this user case.
I'm closing this issue with this action point and the solution for the original bug reported in my comment above.
If you're experiencing this issue with a different setup (maybe you're not using webpack like in this example), then the first thing you should check is that peer dependencies like react and its subpaths should not be bundled with your component library.
If you're still experiencing this and is not solved by the proposed solution, then please feel free to re-open this issue or create a new one.
@DiegoAndai, Can you please reopen this issue? Or would it be better to create a new issue?
If anyone has a case where they encountered a key warning in Micro Frontend and solved it, I'd love to hear about it.
My environment was set up like this
- monorepo + pnpm
- vite
- vite-plugin-federation (for Module Federation)
- React + TS
- MUI v5.15.5
And I've created a simple prototype that you can use to check this out, so you can see the problem.
- Mui key warning test Repository
- See Getting Started for the steps to reproduce.
Additional comments
- Seeing that it happens for all components in material-ui that use
focusTrap, I'm guessing that it's becausefocusTrapdoesn't pass a key when usingReact.cloneElementin production bundling, as mentioned above(But I can't even figure out how to apply the above solution when bundling remoteApps in a vite-plugin-federation.🤣). - When I create a reproduce repo, it doesn't happen when I deploy the host app in production mode (e.g. vite preview, pm2 serve ...).
It would be great to find a solution, but I'd also like to know the cause, is there anyone who can help?
