列表中的每个孩子都应该有一个唯一的“键”

时间:2019-07-13 05:28:09

标签: javascript html reactjs

新的反应方式,无法理解它为什么给出-Each child in a list should have a unique "key", 尽管我添加了key? 而且line-through无法正常工作。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <script src="react.16.8.6.development.js"></script>
        <script src="react-dom.16.8.6.development.js"></script>
        <script src="babel.7.5.4.min.js"></script>
    </head>

    <body>
        <br>
        <div id="container"></div>

        <script type="text/babel">
            class ListItem extends React.Component{
                constructor(props){
                    super(props)
                    this.state = {isDone : false}
                }

                handleClick(){
                    var currentState = !this.state.isDone
                    this.setState({isDone : currentState})
                    console.log("handleClick : currentState = " + currentState)
                }

                render(){
                    var lineStyle = this.state.isDone ? "line-through" : "normal"
                    console.log("render : lineStyle = " + lineStyle + " : this.props.text = " + this.props.text)
                    return(
                        <li key={this.props.id.toString()}
                        onClick={this.handleClick.bind(this)} 
                        style = {{textDecoratipn:lineStyle}}>{this.props.text}
                        </li>
                    );
                }
            }

            class DynamicList extends React.Component{
                render(){
                    return(
                        <ul>
                        {this.props.listItems.map(function(item) {
                            return (<ListItem id={item.id} text={item.text}/>)
                            })
                        }
                        </ul>
                    )
                }
            }

            class MyApp extends React.Component{
                constructor(props){
                    super(props)
                    this.state = {id : 0, listItems : []}
                }
                onAdd(){
                    // e.preventDefault()
                    var textValue = document.getElementById("newItem").value

                    console.log("onAdd : textValue = " + textValue)

                    if(textValue){
                        var newItem =  {id : this.state.id, text : textValue}
                        var newListItems = this.state.listItems;
                        newListItems = newListItems.concat(newItem);

                        this.setState({id : (this.state.id + 1), listItems : newListItems})
                    }
                }

                render(){
                    return(
                        <div>
                        <input id="newItem" placeholder="New Item"></input>
                        <button onClick={this.onAdd.bind(this)}>Add</button>
                        <br/>
                        <DynamicList listItems={this.state.listItems}/>
                        </div>
                    )
                }
            }

            ReactDOM.render(
                <MyApp/>,
                document.getElementById("container")
            )

        </script>
    </body>
</html>

2 个答案:

答案 0 :(得分:4)

使用.map()渲染元素列表时,需要包括一个key属性:

class DynamicList extends React.Component {
    render() {
        return (
            <ul>
            {this.props.listItems.map(function(item) {
                // Include the key in ListItem
                return (<ListItem id={item.id} key={item.id} text={item.text}/>)
            })}
            </ul>
        )
    }
}

对于line-through不起作用,您拼错了textDecoration

<li key={this.props.id.toString()}
    onClick={this.handleClick.bind(this)} 
    style = {{ textDecoration:lineStyle }}> 
    {this.props.text}
</li>

答案 1 :(得分:1)

key是一个特殊的字符串属性,在创建元素列表时需要包括在内。

docs

  

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

因此,您需要在此处添加key

{this.props.listItems.map(function(item) {
  return (<ListItem id={item.id} key={item.id} text={item.text}/>) //key added here
  })
}