React setState不适用于array.prototype.splice

时间:2015-09-06 01:30:39

标签: javascript reactjs

我正在关注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'));

2 个答案:

答案 0 :(得分:0)

splice直接修改数组并返回拼接的项目。因此,如果您将friends设置为this.state.friends.splice(findIndex,1),则会将其设置为&#34;已删除&#34;项目(S)。我猜的根本不是你想要的。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

但是,你知道,你所说的只是&#34;删除不会正常工作&#34;所以你还没有真正说明发生了什么或是什么你想要发生......

答案 1 :(得分:0)

这是一个非常有趣的问题,需要参考最基本的状态渲染。 仅在状态更改时,React才会重新渲染。

此处的“已更改”表示状态指向另一个对象。如果状态更改了其值,但仍指向同一对象,则不会发生重新渲染。

更具体地说:

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)) 
})
相关问题