React setState不适用于array.prototype.splice

问题描述 投票:0回答:2

我正在关注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'));
javascript reactjs
2个回答
0
投票

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

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

但是,您所知道的只是“删除无法正常工作”,因此您尚未真正说明正在发生的事情或想要发生的事情...


0
投票

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

“已更改”在这里表示状态指向另一个对象。如果状态更改了其值,但仍指向同一对象,则不会进行重新渲染。

更具体地说:

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)) 
})
© www.soinside.com 2019 - 2024. All rights reserved.