[英]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
是需要区分的兄弟元素,而不是input
或label
元素。
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.