简体   繁体   English

收到警告“警告:列表中的每个孩子都应该有一个唯一的”key“道具。” 当我的组件渲染时

[英]Getting warning “Warning: Each child in a list should have a unique ”key“ prop.” when my component render

I am trying to get rid of this warning in my react app:我试图在我的反应应用程序中摆脱这个警告:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `SettingRadioButtonGroup`. See https://reactjs.org/link/warning-keys for more information.
    at div
    at SettingRadioButtonGroup (http://localhost:3000/main_window/index.js:92979:171)
    at div
    at CardBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at http://localhost:3000/main_window/index.js:50905:22
    at AccordionCollapse (http://localhost:3000/main_window/index.js:49335:23)
    at div
    at Card (http://localhost:3000/main_window/index.js:49995:23)
    at div
    at SettingGroup (http://localhost:3000/main_window/index.js:92935:15)
    at TestSettingGroup (http://localhost:3000/main_window/index.js:93093:22)
    at div
    at Accordion (http://localhost:3000/main_window/index.js:49282:96)
    at div
    at ModalBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at div
    at ModalDialog (http://localhost:3000/main_window/index.js:53383:23)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at Fade (http://localhost:3000/main_window/index.js:51637:24)
    at DialogTransition
    at Modal (http://localhost:3000/main_window/index.js:84195:24)
    at Modal (http://localhost:3000/main_window/index.js:53061:23)
    at App (http://localhost:3000/main_window/index.js:92660:22)

Here is the code of my SettingRadioButtonGroup components:这是我的SettingRadioButtonGroup组件的代码:

import { nanoid } from "nanoid";
import React, { useState } from "react";
import { Form, InputGroup } from "react-bootstrap";

export type RadioButtonGroup = {
  desc: string;
  isSelected: boolean;
};

export interface SettingRadioButtonGroupProps
{
  groupDesc: string;
  radioButtons: RadioButtonGroup[];
  onRadioSelected: (selectedItem: string) => void;
};

export function SettingRadioButtonGroup(props: SettingRadioButtonGroupProps)
{
  const radioGroupName = nanoid();
  return (
    <div className="radio-group">
      <p className="radio-label">{props.groupDesc}</p>
      <div className="group">
        {
          props.radioButtons.map((button) =>
          {
            if (button.isSelected)
              props.onRadioSelected(button.desc);

            const buttonLabel = nanoid();
            return (
              <div className="radio-button">
                <input type="radio" id={buttonLabel} name={radioGroupName} onClick={() => { () => props.onRadioSelected(button.desc) }} />
                <label htmlFor={radioGroupName}>{button.desc}</label>
              </div>
            );
          })
        }
      </div>
    </div>
  );
}

Here is the component that generate this components:这是生成此组件的组件:

import { useState } from "react";
import { TextBoxSetting } from "./Components/TextBoxSetting";
import { SettingGroup } from "./Components/SettingGroup";
import SettingGroupBaseProps from "./Components/SettingGroupBaseProps";
import { RadioButtonGroup, SettingRadioButtonGroup } from "./Components/SettingRadioButtonGroup";
import faker from  "faker/locale/fr_CA";

export default function TestSettingGroup(props: SettingGroupBaseProps)
{
  const [textInput, setTextInput] = useState<string>();

  const radioButton: RadioButtonGroup[] = [];
  for (let i = 0; i <= 8; i++) {
    radioButton.push({
      desc: faker.lorem.word(),
      isSelected: false
    })
  }

  const [buttonSelected, setButtonSelected] = useState<string>();
  import("lodash")
    .then((_) =>
    {
      const selected = _.find(radioButton, (value) => value.isSelected);
      if (selected)
        setButtonSelected(selected.desc);
    })
    .catch();



  function onSave()
  {

    const settings = {
      textBoxSetting: textInput,
      radioButtonSelected: buttonSelected
    };

    console.table(settings);
  }


  return (
    <SettingGroup name={props.name} desc={props.desc} onSave={onSave}>
      <TextBoxSetting onTextEntered={(e) => setTextInput(e)} name="Text box setting component" />
      <SettingRadioButtonGroup groupDesc={"Radio button group"} radioButtons={radioButton} onRadioSelected={setButtonSelected} />
    </SettingGroup>
  );
}

I tried to get rid of the warning by assigning a random id to the key property as follow however I still have the warning and it caused the component to create a bug where it generate an new radio button when I click a radio button.我试图通过为 key 属性分配一个随机 id 来消除警告,如下所示,但是我仍然有警告,它导致组件创建一个错误,当我单击单选按钮时它会生成一个新的单选按钮。 It also create the following warning:它还会创建以下警告:

Warning: Encountered two children with the same key, `tvehx36gLi-hG56z68RTg`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
    at div
    at div
    at div
    at SettingRadioButtonGroup (http://localhost:3000/main_window/index.js:92980:171)
    at div
    at CardBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at http://localhost:3000/main_window/index.js:50905:22
    at AccordionCollapse (http://localhost:3000/main_window/index.js:49335:23)
    at div
    at Card (http://localhost:3000/main_window/index.js:49995:23)
    at div
    at SettingGroup (http://localhost:3000/main_window/index.js:92935:15)
    at TestSettingGroup (http://localhost:3000/main_window/index.js:93094:22)
    at div
    at Accordion (http://localhost:3000/main_window/index.js:49282:96)
    at div
    at ModalBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at div
    at ModalDialog (http://localhost:3000/main_window/index.js:53383:23)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at Fade (http://localhost:3000/main_window/index.js:51637:24)
    at DialogTransition
    at Modal (http://localhost:3000/main_window/index.js:84195:24)
    at Modal (http://localhost:3000/main_window/index.js:53061:23)
    at App (http://localhost:3000/main_window/index.js:92660:22)
overrideMethod @ react_devtools_backend.js:2430
printWarning @ react-dom.development.js:67
error @ react-dom.development.js:43
warnOnInvalidKey @ react-dom.development.js:13620
reconcileChildrenArray @ react-dom.development.js:13651
reconcileChildFibers @ react-dom.development.js:14125
reconcileChildren @ react-dom.development.js:16990
updateHostComponent @ react-dom.development.js:17632
beginWork @ react-dom.development.js:19080
beginWork$1 @ react-dom.development.js:23940
performUnitOfWork @ react-dom.development.js:22776
workLoopSync @ react-dom.development.js:22707
renderRootSync @ react-dom.development.js:22670
performSyncWorkOnRoot @ react-dom.development.js:22293
(anonymous) @ react-dom.development.js:11327
unstable_runWithPriority @ scheduler.development.js:646
runWithPriority$1 @ react-dom.development.js:11276
flushSyncCallbackQueueImpl @ react-dom.development.js:11322
flushSyncCallbackQueue @ react-dom.development.js:11309
discreteUpdates$1 @ react-dom.development.js:22420
discreteUpdates @ react-dom.development.js:3756
dispatchDiscreteEvent @ react-dom.development.js:5889
9react_devtools_backend.js:2430 Warning: Encountered two children with the same key, `wFq9eikLw6B_LN98bUqCV`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
    at div
    at div
    at div
    at SettingRadioButtonGroup (http://localhost:3000/main_window/index.js:92980:171)
    at div
    at CardBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at http://localhost:3000/main_window/index.js:50905:22
    at AccordionCollapse (http://localhost:3000/main_window/index.js:49335:23)
    at div
    at Card (http://localhost:3000/main_window/index.js:49995:23)
    at div
    at SettingGroup (http://localhost:3000/main_window/index.js:92935:15)
    at TestSettingGroup (http://localhost:3000/main_window/index.js:93094:22)
    at div
    at Accordion (http://localhost:3000/main_window/index.js:49282:96)
    at div
    at ModalBody (http://localhost:3000/main_window/index.js:56308:27)
    at div
    at div
    at ModalDialog (http://localhost:3000/main_window/index.js:53383:23)
    at div
    at Transition (http://localhost:3000/main_window/index.js:85807:30)
    at Fade (http://localhost:3000/main_window/index.js:51637:24)
    at DialogTransition
    at Modal (http://localhost:3000/main_window/index.js:84195:24)
    at Modal (http://localhost:3000/main_window/index.js:53061:23)
    at App (http://localhost:3000/main_window/index.js:92660:22)
import { nanoid } from "nanoid";
import React, { useState } from "react";
import { Form, InputGroup } from "react-bootstrap";
import { RadioButtonGroup } from "./SettingRadioButtonGroup";


export interface SettingCheckboxButtonGroupProps
{
  groupDesc: string;
  checkboxButtons: RadioButtonGroup[];
  onCheckboxSelected: (selectedItem: string) => void;
};

export function SettingChecboxButtonGroup(props: SettingCheckboxButtonGroupProps)
{
  const radioGroupName = nanoid();
  return (
    <div className="radio-group">
      <p className="radio-label">{props.groupDesc}</p>
      <div className="group">
        {
          props.checkboxButtons.map((button) =>
          {
            if (button.isSelected)
              props.onCheckboxSelected(button.desc);

            const buttonLabel = nanoid();
            return (
              <div className="radio-button">
                <input key={radioGroupName} type="checkbox" id={buttonLabel} name={radioGroupName} onClick={() => { () => props.onCheckboxSelected(button.desc); }} />
                <label key={radioGroupName} htmlFor={radioGroupName}>{button.desc}</label>
              </div>
            );
          })
        }
      </div>
    </div>
  );
}

You need to put the key on the outer-most element in the map .您需要将密钥放在map的最外层元素上。

Element keys only distinguish an element from its siblings relative to their parent.元素键仅将元素与其相对于其父元素的兄弟元素区分开来。 Here the div s are the siblings that need to be distinguished, rather than the input or label elements.这里的div是需要区分的兄弟元素,而不是inputlabel元素。

Example:例子:

<div key={radioGroupName} className="radio-button">
    <input type="checkbox" id={buttonLabel} name={radioGroupName} onClick={() => { () => props.onCheckboxSelected(button.desc); }} />
    <label htmlFor={radioGroupName}>{button.desc}</label>
</div>

Also keys serve to give dynamically generated elements (in a loop/ map ) a stable identity, so I wouldn't recommend using randomly generated keys unless you're storing those in state so that they're stable as well (if all the keys are regenerated and change on every rerender, there is no point in assigning keys).密钥还用于为动态生成的元素(在循环/ map )提供稳定的身份,因此我不建议使用随机生成的密钥,除非您将它们存储在 state 中,以便它们也稳定(如果所有密钥每次重新渲染都会重新生成并更改,分配键没有意义)。 Check out the docs on keys for more info.查看有关密钥的文档以获取更多信息。

In React, every time you ara going to render a sequence of items from an array, using for example a map function, you have to provide a unique key for every item to help React's engine recognize each one, in your example, you can do something like this to fix:在 React 中,每次你要渲染数组中的一系列项目时,例如使用map function,你必须为每个项目提供一个唯一的键来帮助 React 的引擎识别每个项目,在你的例子中,你可以这样做像这样修复:

props.radioButtons.map((button, index) =>
  {
    if (button.isSelected)
      props.onRadioSelected(button.desc);

    const buttonLabel = nanoid();
    return (
      <div key={buttonLabel} className="radio-button">
        <input type="radio" id={buttonLabel} name={radioGroupName} onClick={() => { () => props.onRadioSelected(button.desc) }} />
        <label htmlFor={radioGroupName}>{button.desc}</label>
      </div>
    );
  })
}

Check the change at <div key={buttonLabel} className="radio-button"><div key={buttonLabel} className="radio-button">检查更改

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 检查 `RenderComments` 的渲染方法 - Warning: Each child in a list should have a unique "key" prop. Check the render method of `RenderComments` 正在渲染对象数组的数组,不断得到“警告:列表中的每个孩子都应该有一个唯一的“键”道具。 - Was rendering arrays of arrays of objects, keep getting “Warning: Each child in a list should have a unique ”key“ prop.” 警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 检查元素时不显示关键道具 - Warning: Each child in a list should have a unique “key” prop. Key prop doesn't show when inspect element 警告:数组或迭代器中的每个子代均应具有唯一的“键”道具。 检查`单位`的渲染方法 - Warning: Each child in an array or iterator should have a unique “key” prop. Check the render method of `Units` 警告:数组或迭代器中的每个子代均应具有唯一的“键”道具。 检查“搜索”的渲染方法 - Warning: Each child in an array or iterator should have a unique “key” prop. Check the render method of 'search' 警告:列表中的每个孩子都应该有一个唯一的“key”道具。 即使已经设置了密钥 - Warning: Each child in a list should have a unique "key" prop. Even after setting the key already 警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 mapStateToProps - Warning: Each child in a list should have a unique "key" prop. mapStateToProps 警告:列表中的每个孩子都应该有一个唯一的“key”道具。 - ReactJS - Warning: Each child in a list should have a unique "key" prop. - ReactJS 警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 如何解决这个问题? - Warning: Each child in a list should have a unique "key" prop. how to fix this? 警告:数组或迭代器中的每个子代都应具有唯一的“键”道具。 li中已添加的关键道具 - Warning: Each child in an array or iterator should have a unique “key” prop.; key prop already added in li
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM