React的修改state的错误相关问题以及解决方法?

业务需求是这样的:
可以通过按钮,动态加载/删除一个块,这个块里有相关的输入信息

我想到的解决方案:
通过state,定义一个数组,通过修改这个数组,来实现页面加载。

假设实现方法:

<Button onClick={this.add}>add</Button>
<Button onClick={this.remove(index)}>remove</Button>

add(){
    const temp = this.state.list;
    list.push(...);
    this.setState({
        list:temp
    })
}

remove(index){
    const temp = this.state.list;
    list.splice(index,1);
    this.setState({
        list:temp
    })
}

这样出现了的问题:

Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount

查了一下,说是因为render这种需要props和state进行渲染的方法中,不能再对props和state进行更新。我的理解是,React会在props和state改变的时候调用 render进行DOM diff然后渲染,如果在渲染过程中再对props和states进行更改,就陷入死循环了。

于是就重新改成了匿名函数:

<Button onClick={(index)=>{this.remove(index)}}>remove</Button>

问题是解决了,但是又看到说尽量不要用匿名函数,容易出现性能问题。
不知道各位有什么好的意见或建议?

阅读 7.1k
2 个回答

报错的原因楼上@michael_cai已经讲的很清楚了,我就不重复了。

每次渲染都重新绑定N次也会有些性能问题 -- 这种场景下,我习惯这样做:

<!-- 把index保存在data-index上,然后在事件处理函数中通过dataset来获取index -->
<Button onClick={this.remove} data-index={index}>remove</Button>
remove(event){
    const index = event.currentTarget.dataset.index
    const temp = this.state.list;
    temp.splice(index,1);
    this.setState({
        list:temp
    })
}
<Button onClick={this.remove(index)}>remove</Button>

这么写的话,在render的时候就会执行remove函数,不是click的时候执行。
至于匿名函数的性能问题,从何而来,根据是什么?

非得纠结的话,就这样用

<Button onClick={this.remove.bind(this,index)}>remove</Button>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏