我正在关注here中的一个反应教程,并尝试添加删除按钮以删除列表中的名称。但是,如果我在setState方法中设置了friends:this.state.friends.splice(findIndex,1)
,则删除操作将无法正常进行,但是,如果我在setState方法之外设置了this.state.friends.splice(findIndex,1)
,则删除将起作用,有人可以解释为什么吗?谢谢(这里是jsfiddle)。(编辑:这是链接中的jsx)
var HelloHandler = React.createClass({
getInitialState: function(){
return{
name: 'Tyler McGinnis',
friends: ['Jake Lingwall', 'Murphy Randall', 'Merrick Christensen']
}
},
addFriend: function(friend){
this.setState({
friends: this.state.friends.concat([friend])
})
},
deleteFriend: function(name){
findIndex=this.state.friends.indexOf(name);
this.state.friends.splice(findIndex,1)//
this.setState({
friends: this.state.friends
//delete won't work properly if change to friends:this.state.friends.splice(findIndex,1)
})
},
render: function(){
return (
<div>
<div>
Hello{this.state.name}
</div>
<div>
<PrintFriends friendList={this.state.friends} deleteFriend={this.deleteFriend}/>
</div>
<div>
<AddFriend addFriend={this.addFriend} />
</div>
</div>
)
}
});
var AddFriend=React.createClass({
getInitialState: function(){
return {
inputName:''
}
},
setFriendNameToState: function(evt){
this.setState({
inputName: evt.target.value
})
},
updateFriendNameToList: function(){
this.props.addFriend(this.state.inputName);
this.setState({
inputName: ''
})
},
render: function(){
return(
<div>
<input type='text' onChange={this.setFriendNameToState} />
<button onClick={this.updateFriendNameToList}>update list</button>
</div>
)
}
});
PrintFriends=React.createClass({
deleteName: function(people){
this.props.deleteFriend(people.name);
},
render: function(){
var self=this;
nameList=this.props.friendList.map(function(name){
return(
<li key={name}>
{name} <button onClick={this.deleteName.bind(null,{name})}>delete</button>
</li>
)
}.bind(self));
return(
<div>
<h3> Friends </h3>
<ul>
{nameList}
</ul>
</div>
)
}
})
React.render(<HelloHandler />, document.getElementById('app'));
splice
直接修改数组并返回已拼接的项目。因此,如果将friends
设置为this.state.friends.splice(findIndex,1)
,则将其设置为“已删除”项目。我猜测的根本不是您想要的。
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
但是,您所知道的只是“删除无法正常工作”,因此您尚未真正说明正在发生的事情或想要发生的事情...
这是一个非常有趣的问题,需要参考最基本的状态渲染。仅在状态更改时才进行重新渲染。
“已更改”在这里表示状态指向另一个对象。如果状态更改了其值,但仍指向同一对象,则不会进行重新渲染。
更具体地说:
friends = ['Amy', 'Beatrix', 'Cedric']
friends.splice(0,1) // friends === ['Beatrix', 'Cedric'], however, it still points to the same object.
要使其正常工作,您应该改用过滤器:
// filter return a new object
this.setState({
friends: friends.filter((value, index) => index!==findIndex)
})
另一种方法,如果数组足够简单
// JSON.parse return a new object
this.setState({
friends: JSON.parse(JSON.stringify(this.state.friends))
})