警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS

Posted

技术标签:

【中文标题】警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS【英文标题】:Warning: Each child in a list should have a unique "key" prop. - ReactJS 【发布时间】:2019-12-07 01:17:48 【问题描述】:

我正在使用 ReactJS 构建一个看板应用程序,用户可以将“卡片”添加到三个不同的“列”(Todos、Onprogress 和 Done)。我遇到的问题是应该在卡片中显示的内容没有按应有的方式显示,尽管我的状态正在返回它的对象就好了(当我 console.log 一切时)。我认为问题在于我将一个对象推入一个数组,然后将它作为一个值添加到我的状态键之一,因此,当我使用道具传递它时,我的数据没有被正确读取。我将在下面分享我所有的代码库。

这是我的应用组件:

import React,  Component  from 'react';
  import Column from './Column';
  import AddCardForm from './AddCardForm';
  import './App.css';

class App extends Component 
    constructor(props) 
      super(props)
      this.state = 
        columns: [
          
            name: 'Todos',
            cards: []
          ,
          
            name: 'Onprogress',
            cards: []
          ,
          
            name: 'Done',
            cards: []
          , 
        ] 
      ;
    ;

    // componentDidMount() 
    //   const  coldata  = this.state.columns
    //   console.log(coldata);
    //   // this.ref = base.syncState();
    // 

    addCard = (card, otherStatus) => 
      console.log("Adding a Card");
      const cards =  ...this.state.columns.cards ;
      cards[`card`] = card;
      
      let todosCards = []
      let onprogressCards = []
      let doneCards = []
      
      Object.values(otherStatus).map(function(value) 
        if (value.includes('Onprogress') && value.includes('Done')) 
              todosCards.push(cards)
         else if (value.includes('Todos') && value.includes('Done')) 
              onprogressCards.push(cards);
         else if (value.includes('Todos') && value.includes('Onprogress')) 
              doneCards.push(cards);
        
        return(todosCards || onprogressCards || doneCards);  
      );

      console.log(todosCards);
      console.log(onprogressCards);
      console.log(doneCards);

        this.setState(
          columns: [
             
              name: 'Todos',
              cards: todosCards
            ,
             
              name: 'Onprogress',
              cards: onprogressCards
            ,
             
              name: 'Done',
              cards: doneCards
            ,
          ] 
        );
    
        
  render() 
    return (
  <div className="App">
   Object.keys(this.state.columns).map(key => (
      <Column key=key details=this.state.columns[key] />
    ))
      <AddCardForm addCard=this.addCard />
  </div>
    );
  

export default App;

这是我的专栏组件:

import React, Component from "react";
import Card from "./Card"


class Column extends Component 
    render() 
        return (
        <div className="column"> 
            <h1 className="Title">this.props.details.name</h1>
            Object.keys(this.props.details.cards).map( keycard => (
                <Card keycard=keycard data=this.props.details.cards[keycard] /> 
            ))     
        </div>
        );
    


export default Column;

这是我的卡片组件:

    import React, Component from "react";


    class Card extends Component 
        render() 
            const taskName, taskDescription, taskPeriod  = this.props.data;
            // const isTaskOn = taskStatus 
            return (
            <div className="card">
                <span className="title">taskName</span>
                <div className="description">
                    <h4>taskDescription</h4>
                </div>
                <div className="period">
                    <h4>taskPeriod</h4>
                </div>
                <div className="status">
                    <select>
                        <option value='Todos'>Todos</option>
                        <option value='Onprogress'>Onprogress</option>
                        <option value="Done">Done</option>
                    </select>
                </div>
            </div>  
            );
        
    

    export default Card;

这是我的 AddCardForm 组件:

import React,  Component  from 'react';


class AddCardForm extends Component 

    taskName = React.createRef();
    taskDescription = React.createRef();
    taskPeriod = React.createRef();
    taskStatus = React.createRef(); 

    addCardtoApp = event => 
        event.preventDefault();
        const card = 
            taskName: this.taskName.current.value, 
            taskDescription: this.taskDescription.current.value,
            taskPeriod: this.taskPeriod.current.value,
        ;
        const cardStatus = this.taskStatus.current.value;
        let otherStatus = 
            otherStatus: this.taskStatus.current.textContent.replace(`$cardStatus`, ''),
        ;
        
        this.props.addCard(card, otherStatus);
        event.currentTarget.reset();
    ;
    
    render() 
        return (
        <form onSubmit=this.addCardtoApp>
        <label>
            Task Name:
            <input type="text" name="taskName" ref=this.taskName/>
        </label> <br />
        <label>
            Description:
            <input type="text" name="taskDescription" ref=this.taskDescription />
        </label> <br /> 
        <label>
            Period:
            <input type="text" name="taskPeriod" ref=this.taskPeriod />
        </label> <br />
        <label>
            Task Status:
            <select type="text" name="taskStatus" ref=this.taskStatus>
                <option value="Todos">Todos</option>
                <option value="Onprogress">Onprogress</option>
                <option value="Done">Done</option>
            </select>
        </label> <br />
        <input type="submit" value="Submit" />
        </form>
        );
    


export default AddCardForm;

【问题讨论】:

首先阅读key 的工作原理以及为什么需要它reactjs.org/docs/lists-and-keys.html 【参考方案1】:

来自反应文档:

键帮助 React 识别哪些项目已更改、添加或删除。应为数组内的元素赋予键,以使元素具有稳定的身份

因此,本质上,如果您将数组映射到组件,则为每个组件(映射的)拥有唯一的键将确保仅在必要时重新渲染这些组件。

请关注this documentation,您将了解警告想要深入告诉您的内容。

【讨论】:

【参考方案2】:

您在使用循环构建 React 组件的任何地方都必须添加 prop key 并为其传递一个唯一值。

您可以像这样重新定义您的 map 调用以包含索引:

Object.keys(this.state.columns).map((count, key) => (
    <Column key=count details=this.state.columns[key] />
))

【讨论】:

以上是关于警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS的主要内容,如果未能解决你的问题,请参考以下文章

如何修复警告:列表中的每个孩子都应该有一个唯一的“关键”道具

添加了关键道具 ||警告:列表中的每个孩子都应该有一个唯一的“关键”道具

React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具

警告:列表中的每个孩子都应该有一个唯一的“关键”道具。反应.js

警告:列表中的每个孩子都应该有一个唯一的“关键”道具

如何找到警告的原因:列表中的每个孩子都应该有一个唯一的“关键”道具