Reputation: 1026
New to react, can not understand why it is giving - Each child in a list should have a unique "key"
,
Though I have added key
?
And line-through
is not working.
<!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>
Upvotes: 2
Views: 215
Reputation: 1464
When you're using .map()
to render a list of elements, you need to include a key
attribute:
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>
)
}
}
As for line-through
not working, you misspelled textDecoration
:
<li key={this.props.id.toString()}
onClick={this.handleClick.bind(this)}
style = {{ textDecoration:lineStyle }}>
{this.props.text}
</li>
Upvotes: 4
Reputation: 20765
A key
is a special string attribute you need to include when creating lists of elements.
From the docs,
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
So your need to add key
here,
{this.props.listItems.map(function(item) {
return (<ListItem id={item.id} key={item.id} text={item.text}/>) //key added here
})
}
Upvotes: 1