我正在尝试在我的 React 应用程序中消除此警告:
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)
这是我的 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>
);
}
这是生成此组件的组件:
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>
);
}
我试图通过为关键属性分配一个随机 ID 来消除警告,如下所示,但我仍然有警告,并且它导致组件创建一个错误,当我单击单选按钮时,它会生成一个新的单选按钮。它还会创建以下警告:
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>
);
}
最佳答案
您需要将键放在map
中最外层的元素上。
元素键仅区分元素与其相对于其父元素的兄弟元素。这里的 div
是需要区分的兄弟元素,而不是 input
或 label
元素。
示例:
<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>
此外,键还可以为动态生成的元素(在循环/map
中)提供稳定的标识,因此我不建议使用随机生成的键,除非您将它们存储在状态中,以便它们也很稳定(如果所有 key 都重新生成并在每次重新渲染时发生变化,则分配 key 就没有意义)。查看docs on keys了解更多信息。
关于javascript - 当我的组件渲染时收到警告 "Warning: Each child in a list should have a unique "key"prop.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66212373/