Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[material-ui][Autocomplete] React keys being passed directly to JSX without using spread #41486

Closed
Chukwu3meka opened this issue Mar 13, 2024 · 4 comments
Labels
component: autocomplete This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material status: waiting for author Issue with insufficient information

Comments

@Chukwu3meka
Copy link

Chukwu3meka commented Mar 13, 2024

Steps to reproduce

import Ellipsis from "components/shared/ellipsis";

import { SearchOutlined as SearchIcon } from "@mui/icons-material";
import { SearchProps } from "interfaces/components/apihub.interface";
import { TextField, Autocomplete, Divider, Stack, Typography, Box, IconButton } from "@mui/material";

const Search = ({ searchResult, onInputChange, onValueChange, value, inputValue, getEndpoint, isOptionEqualToValue }: SearchProps) => (
  <Autocomplete
    fullWidth
    value={value}
    options={searchResult}
    inputValue={inputValue}
    onChange={(e, newValue) => onValueChange(newValue)}
    onInputChange={(e, newInputValue) => onInputChange(newInputValue)}
    filterOptions={(options) => options} // Return all options without filtering
    isOptionEqualToValue={(option, value) => isOptionEqualToValue(option, value)}
    getOptionLabel={(option) => (typeof option === "string" ? inputValue : option.title)}
    renderOption={(props, { title, description, id }) => (
      <Box component="li" mb={1} {...props}>
        <Stack onClick={() => getEndpoint(id)}>
          <Stack direction="row" justifyContent="space-between" alignItems="flex-end" spacing={1} sx={{ width: "100%" }}>
            <Typography maxWidth="80%" fontSize=".8em" noWrap sx={{ textTransform: "uppercase" }}>
              {title}
            </Typography>
          </Stack>

          <Divider sx={{ width: "90%", my: 1, alignSelf: "flex-end" }} />

          <Ellipsis lines={2} display="block" variant="caption" color="text.secondary" sx={{ mt: 0.5, ml: 2 }}>
            {description}
          </Ellipsis>
        </Stack>
      </Box>
    )}
    // renderInput={(params) => <TextField {...params} placeholder="Start typing to search" inputProps={{ ...params.inputProps }} />}

    renderInput={(params) => (
      <TextField
        sx={{ mt: 2 }}
        {...params}
        label={
          <Stack direction="row">
            <IconButton aria-label="mongodb" component="span" sx={{ mt: -1 }}>
              <SearchIcon />
            </IconButton>
            Start typing to search endpoints
          </Stack>
        }
      />
    )}
  />
);

export default Search;

Current behavior

Error happens once server returns matching results. Adding key to <Box component="li" mb={1} {...props}> does not solve the issue

Expected behavior

No response

Context

Warning: A props object containing a "key" prop is being spread into JSX:
let props = {key: someKey, component: ..., mb: ..., tabIndex: ..., role: ..., id: ..., onMouseMove: ..., onClick: ..., onTouchStart: ..., data-option-index: ..., aria-disabled: ..., aria-selected: ..., className: ..., children: ...};
<ForwardRef(Box) {...props} />
React keys must be passed directly to JSX without using spread:
let props = {component: ..., mb: ..., tabIndex: ..., role: ..., id: ..., onMouseMove: ..., onClick: ..., onTouchStart: ..., data-option-index: ..., aria-disabled: ..., aria-selected: ..., className: ..., children: ...};
<ForwardRef(Box) key={someKey} {...props} />
at Autocomplete (webpack-internal:///(app-pages-browser)/./node_modules/@mui/material/Autocomplete/Autocomplete.js:511:85)
at Search (webpack-internal:///(app-pages-browser)/./components/apihub/search/Search.tsx:17:11)
at SearchContainer (webpack-internal:///(app-pages-browser)/./components/apihub/search/SearchContainer.tsx:13:11)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Box (webpack-internal:///(app-pages-browser)/./node_modules/@mui/system/esm/createBox.js:36:76)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Grid (webpack-internal:///(app-pages-browser)/./node_modules/@mui/system/esm/Stack/createStack.js:160:24)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Box (webpack-internal:///(app-pages-browser)/./node_modules/@mui/system/esm/createBox.js:36:76)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Grid (webpack-internal:///(app-pages-browser)/./node_modules/@mui/material/Grid/Grid.js:387:89)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Grid (webpack-internal:///(app-pages-browser)/./node_modules/@mui/material/Grid/Grid.js:387:89)
at div
at eval (webpack-internal:///(app-pages-browser)/./node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js:60:66)
at Box (webpack-internal:///(app-pages-browser)/./node_modules/@mui/system/esm/createBox.js:36:76)
at EndpointsIntro (webpack-internal:///(app-pages-browser)/./components/apihub/endpoints/EndpointsIntro.tsx:18:11)
at main
at EndpointsContainer (webpack-internal:///(app-pages-browser)/./components/apihub/endpoints/EndpointsContainer.tsx:17:92)
at ConnectFunction (webpack-internal:///(app-pages-browser)/./node_modules/react-redux/dist/react-redux.mjs:875:74)
at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:242:11)
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:340:11)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:161:11)
at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:152:9)
at ScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:227:11)
at RenderFromTemplateContext (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/render-from-template-context.js:16:44)
at OuterLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:359:11)
at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:242:11)
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:340:11)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:161:11)
at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:152:9)
at ScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:227:11)
at RenderFromTemplateContext (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/render-from-template-context.js:16:44)
at OuterLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:359:11)
at div
at ApiHubLayout (webpack-internal:///(app-pages-browser)/./components/layouts/apihub-layout/ApihubLayout.tsx:11:11)
at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:242:11)
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:76:9)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at Suspense
at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:340:11)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:161:11)
at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:152:9)
at ScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:227:11)
at RenderFromTemplateContext (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/render-from-template-context.js:16:44)
at OuterLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:359:11)
at SWRConfig (webpack-internal:///(app-pages-browser)/./node_modules/swr/dist/_internal/index.mjs:571:13)
at ThemeProvider (webpack-internal:///(app-pages-browser)/./node_modules/@mui/private-theming/ThemeProvider/ThemeProvider.js:42:5)
at ThemeProvider (webpack-internal:///(app-pages-browser)/./node_modules/@mui/system/esm/ThemeProvider/ThemeProvider.js:59:13)
at Providers (webpack-internal:///(app-pages-browser)/./components/providers/Providers.tsx:19:11)
at ProvidersContainer (webpack-internal:///(app-pages-browser)/./components/providers/ProvidersContainer.tsx:20:13)
at ConnectFunction (webpack-internal:///(app-pages-browser)/./node_modules/react-redux/dist/react-redux.mjs:875:74)
at SnackbarProvider (webpack-internal:///(app-pages-browser)/./node_modules/notistack/notistack.esm.js:1491:24)
at Provider (webpack-internal:///(app-pages-browser)/./node_modules/react-redux/dist/react-redux.mjs:1049:3)
at AppRouterCacheProvider (webpack-internal:///(app-pages-browser)/./node_modules/@mui/material-nextjs/v13-appRouter/appRouterV13.js:26:13)
at RootProviders (webpack-internal:///(app-pages-browser)/./components/providers/RootProviders.tsx:19:11)
at body
at html
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:76:9)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at DevRootNotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/dev-root-not-found-boundary.js:33:11)
at ReactDevOverlay (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:84:9)
at HotReload (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:307:11)
at Router (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js:182:11)
at ErrorBoundaryHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:114:9)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:161:11)
at AppRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js:538:13)
at ServerRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-index.js:129:11)
at RSCComponent
at Root (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-index.js:145:11)

Your environment

npx @mui/envinfo
  Don't forget to mention which browser you used.

Browser used is chrome

  Output from `npx @mui/envinfo` goes here.

  System:
    OS: Windows 11 10.0.22631
  Binaries:
    Node: 20.10.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.2.5 - C:\Program Files\nodejs\npm.CMD
    pnpm: Not Found
  Browsers:
    Chrome: Not Found
    Edge: Chromium (122.0.2365.80)
  npmPackages:
    @emotion/react: ^11.11.4 => 11.11.4
    @emotion/styled: ^11.11.0 => 11.11.0
    @mui/base:  5.0.0-beta.38
    @mui/core-downloads-tracker:  5.15.12
    @mui/icons-material: ^5.15.12 => 5.15.12
    @mui/lab: ^5.0.0-alpha.167 => 5.0.0-alpha.167
    @mui/material: ^5.15.12 => 5.15.12
    @mui/material-nextjs: ^5.15.11 => 5.15.11
    @mui/private-theming:  5.15.12
    @mui/styled-engine:  5.15.11
    @mui/system: ^5.15.12 => 5.15.12
    @mui/types:  7.2.13
    @mui/utils:  5.15.12
    @types/react: ^18 => 18.2.47
    react: ^18.2.0 => 18.2.0
    react-dom: ^18.2.0 => 18.2.0
    typescript: ^5 => 5.3.3

Search keywords: next.js autocomplete

@Chukwu3meka Chukwu3meka added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Mar 13, 2024
@danilo-leal danilo-leal changed the title React keys being passed directly to JSX without using spread in AutoCompplete [material-ui][Autocomplete] React keys being passed directly to JSX without using spread Mar 13, 2024
@danilo-leal danilo-leal added package: material-ui Specific to @mui/material component: autocomplete This is the name of the generic UI component, not the React module! labels Mar 13, 2024
@danilo-leal
Copy link
Contributor

Hey @Chukwu3meka; thanks for opening the issue! Can you provide a reproducible CodeSandbox for better troubleshooting?

@danilo-leal danilo-leal removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Mar 13, 2024
@mj12albert
Copy link
Member

Adding key to <Box component="li" mb={1} {...props}> does not solve the issue

Is this what you tried? <Box component="li" mb={1} {...props} key={props.key}> @Chukwu3meka

@mj12albert mj12albert added the status: waiting for author Issue with insufficient information label Mar 14, 2024
@bmorales-broditec
Copy link

Hi, I have the same issue. I tried @mj12albert's suggestion but it doesn't work for me.

Some of the implementations I have tried and have the same problem:

First

<li {...props}>

// Error
Warning: A props object containing a "key" prop is being spread into JSX:
  let props = {key: someKey, tabIndex: ..., role: ..., id: ..., onMouseMove: ..., onClick: ..., onTouchStart: ..., data-option-index: ..., aria-disabled: ..., aria-selected: ..., className: ..., children: ...};
  <li {...props} />
React keys must be passed directly to JSX without using spread:
  let props = {tabIndex: ..., role: ..., id: ..., onMouseMove: ..., onClick: ..., onTouchStart: ..., data-option-index: ..., aria-disabled: ..., aria-selected: ..., className: ..., children: ...};
  <li key={someKey} {...props} />

Second

<li key={option.id} {...props}>

// Same error

Third

<li {...props} key={option.id}>

// Error
Warning: Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.
But I don't have element with repeated id

Fourth

renderOption={(props, option, { selected }) => {
    const customKey = `${option.id} ${option.name}`
    return (
        <li key={customKey} {...props}>
        
 // Same error

Code

<Autocomplete
  disableCloseOnSelect
  fullWidth
  getOptionLabel={(option) => option.name}
  groupBy={(option) => option.wellnessArea.name}
  multiple
  options={getWellnessCategoriesData?.getWellnessCategories || []}
  renderInput={(params) => (
    <TextField
      {...params}
      helperText={
        t.completeProfilePage.wellnessCategories.categoriesHelperText
      }
      label={t.completeProfilePage.wellnessCategories.categoriesLabel}
      placeholder={
        t.completeProfilePage.wellnessCategories.categoriesPlaceholder
      }
      variant="outlined"
    />
  )}
  renderOption={(props, option, { selected }) => (
    <li key={option.id} {...props}>
      <Checkbox
        checked={selected}
        checkedIcon={checkedIcon}
        icon={icon}
        style={{ marginRight: 8 }}
      />
      {option.name}
    </li>
  )}
  size="medium"
/>

Copy link

Since the issue is missing key information and has been inactive for 7 days, it has been automatically closed. If you wish to see the issue reopened, please provide the missing information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: autocomplete This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material status: waiting for author Issue with insufficient information
Projects
None yet
Development

No branches or pull requests

4 participants