【问题标题】:New to React :: Warning: Each child in a list should have a unique "key" propReact 新手 :: 警告:列表中的每个孩子都应该有一个唯一的“关键”道具
【发布时间】:2020-01-03 10:05:45
【问题描述】:

对 React 非常陌生,我不断收到上面的警告。尝试了各种方法来修复它,但没有运气,代码就是我现在的位置。可能是非常简单的事情,但我就是看不到它。我没有通过 NodeJs 运行 React,它的工作与此警告不同。

BuildList.js 文件

    const ListItem = props => {
    return (
        <li key={`${props.title}${props.index}`} className="my-list" onClick={props.onDelete}>
            {props.title}
        </li>
    )
}
class BuildList extends React.Component {

constructor(props) {
    super(props);
    this.state = {items: props.data};
}

addItemHandler() {
    this.setState(prevState => {
        var newItem = prompt("Enter some text");

        if(newItem) {
            return {items: prevState.items.concat(newItem)};
        }
    });
}

deleteItemHandler(txt) {
    this.setState(prevState => {
        if(confirm('Are you sure?')) {
            return {items: prevState.items.filter(item => {
                    return item !== txt;
                }
            )};
        }
    });
}

render() {
    return (
        <div>
            <p style={{'fontWeight': '700'}}>{this.props.intro}</p>
            <ul className="list-unstyled">
                {this.state.items.map((item, index) => {
                    return (
                        <ListItem key={item} title={item} onDelete={this.deleteItemHandler.bind(this, item)} />
                    )
                })}
            </ul>
            <button onClick={this.addItemHandler.bind(this)} className="btn btn-sm btn-success">Add</button>
        </div>
    )
}
}

app.js 文件

(function(){

//Defaults
const domContainer = document.querySelector('#root');

//Final output
ReactDOM.render(
    [
        <BuildList data = {['Item 1','Item 2', 'Item 3', 'Item 4']} intro="My first React list" />,             
    ], domContainer);
}) ()

以下是完整的警告信息:

react-dom.development.js:524 Warning: Each child in a list should have a unique "key" prop. See LINK TO WEBSITE for more information.
warningWithoutStack @   react-dom.development.js:524
warning @   react-dom.development.js:1012
warnForMissingKey   @   react-dom.development.js:14793
warnOnInvalidKey    @   react-dom.development.js:15259
reconcileChildrenArray  @   react-dom.development.js:15310
reconcileChildFibers    @   react-dom.development.js:15744
reconcileChildren   @   react-dom.development.js:18242
updateHostRoot  @   react-dom.development.js:18713
beginWork$1 @   react-dom.development.js:20336
beginWork$$1    @   react-dom.development.js:25902
performUnitOfWork   @   react-dom.development.js:24841
workLoopSync    @   react-dom.development.js:24817
performSyncWorkOnRoot   @   react-dom.development.js:24416
scheduleUpdateOnFiber   @   react-dom.development.js:23844
updateContainer @   react-dom.development.js:27249
(anonymous) @   react-dom.development.js:27674
unbatchedUpdates    @   react-dom.development.js:24579
legacyRenderSubtreeIntoContainer    @   react-dom.development.js:27673
render  @   react-dom.development.js:27754
(anonymous) @   apps-dist.js:1
(anonymous) @   apps-dist.js:1

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    试试这个

    render() {
        return (
            <div>
                <p style={{'fontWeight': '700'}}>{this.props.intro}</p>
                <ul className="list-unstyled">
                    {this.state.items.map((item, index) => {
                        return (
                            <ListItem key={index} title={item} onDelete={this.deleteItemHandler.bind(this, item)} />
                        )
                    })}
                </ul>
                <button onClick={this.addItemHandler.bind(this)} className="btn btn-sm btn-success">Add</button>
            </div>
        )
    }
    

    【讨论】:

    • 还需要给ListItem组件添加key prop
    • 这不会让警告消失
    • @Martin 您需要将解决方案都添加到您的代码中(&lt;ListItem key={index}&lt;li key={props.key}
    • @Jigar Shah,试过了,仍然得到同样的两个警告
    【解决方案2】:

    您需要将 key 属性添加到您的ListItemcomponent,这样警告就会消失。但是你不能通过 props 传递它,因为它是 React 保留的 prop。

    const ListItem = props => {
      return (
        <li key={`${props.title}${props.index}`} className="my-list" onClick={props.onDelete}>
            {props.title}
        </li>
      )
    }
    
    <ul className="list-unstyled">
      {this.state.items.map((item, index) => {
        return (
          <ListItem key={index} title={item} onDelete={this.deleteItemHandler.bind(this, item)} index={index} />
        )
      })}
    </ul>
    

    您应该尝试连接唯一信息来创建您的密钥道具。仅使用 map 函数的索引不是一个好习惯。

    【讨论】:

    • 刚刚尝试过,仍然收到相同的警告,以及 react.development.js:255 警告:ListItem:key 不是道具。尝试访问它会导致 undefined 被返回。如果您需要在子组件中访问相同的值,则应将其作为不同的 prop 传递
    • 已更新我的代码并编辑了我的问题,但仍然收到警告
    • 尝试将 key={item} 更改为 key={index} 然后
    • 试过了,还是不行。通过添加
    • 极不可能向BuildList 组件添加密钥。我确定您需要在ListItem 组件上添加keyprop。您可以尝试在没有缓存的情况下刷新吗?也许您的浏览器仍然保留旧版本
    【解决方案3】:

    可能是这个原因

    //Final output
    ReactDOM.render(
        [
            <BuildList data = {['Item 1','Item 2', 'Item 3', 'Item 4']} intro="My first React list" />,             
        ], domContainer);
    }) ()
    
    

    在 BuildList 上添加 key prop

    //Final output
    ReactDOM.render(
        [
            <BuildList key={1} data = {['Item 1','Item 2', 'Item 3', 'Item 4']} intro="My first React list" />,             
        ], domContainer);
    }) ()
    
    

    或者不要让它成为一个数组

    //Final output
    ReactDOM.render(
    <BuildList data = {['Item 1','Item 2', 'Item 3', 'Item 4']} intro="My first React list" />,             
      , domContainer);
    }) ()
    

    【讨论】:

    • 您可以编辑您的答案而不是添加另一个答案。
    • @John Pierre Cena,您能解释一下为什么添加 key={1} 可以解决此问题。我需要它作为一个数组,因为我要输出更多选项,但它们与我的警告消息无关
    • @Martin 因为你正在渲染一个数组,所以 react 会为每个索引询问一个键,以便它知道哪个是哪个。在这种情况下,您可以将 BuildList 元素存储到数组变量中并使用 array.map 呈现它。
    【解决方案4】:

    Codesandbox Link

    我已经使用您的代码复制了一个最小示例。添加key={index} 后,我没有看到任何警告。但是,如果您删除“key”属性,您将看到警告。

    【讨论】:

      猜你喜欢
      • 2020-03-01
      • 1970-01-01
      • 2019-08-04
      • 2021-01-12
      • 2022-06-28
      • 1970-01-01
      • 2021-11-18
      • 2023-02-17
      • 2019-12-05
      相关资源
      最近更新 更多