forceUpdate()与带有回调的this.setState()

And*_*ler 7 reactjs

这样做的原因是处理具有state自己功能的变量.我有两种方式可以想到.一种是this.state通过调用状态函数直接变异(好吧,有点,我知道它是不鼓励的),然后调用forceUpdate()并处理它带来的东西.另一种是做回调函数.哪种方法适当?

这是我所谈论的一个例子.我正在使用Vis.js,他们的DataSet对象允许您将数据添加到现有数据集 - 例如节点和边缘.

  addDataToGraph: function(data) {
    // Is this the proper way to do something like this?
    this.state.graphData.nodes.add(nodes);
    this.state.graphData.edges.add(edges);
    this.forceUpdate();

    // Or is this the right way - the question I am posing here
    this.setState({
      currentChunk: data.currentChunk,
      totalChunks: data.totalChunks
    }, function() {
      this.state.graphData.nodes.add(data.nodes);
      this.state.graphData.edges.add(data.edges);
    }.bind(this));
  }
Run Code Online (Sandbox Code Playgroud)

rfu*_*duk 6

你绝对不应该变异this.state或其中的任何东西.来自React Component API文档:

永远不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变.把this.state看作是不可变的.

setState()不会立即改变this.state,但会创建挂起状态转换.调用此方法后访问this.state可能会返回现有值.

无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升.

除非在shouldComponentUpdate()中实现条件呈现逻辑,否则setState()将始终触发重新呈现.如果正在使用可变对象并且无法在shouldComponentUpdate()中实现逻辑,则仅当新状态与先前状态不同时调用setState()将避免不必要的重新呈现.

即使你的第二个例子在这里也不正确,因为你还在改变this.state.第二个参数仅仅是状态更新时的回调.你想要做的是以某种方式获得新对象并给予它们setState.对Vis.js不太熟悉,这似乎有点棘手,因为它似乎没有任何返回全新/不可变数据集的操作.甚至没有复制或克隆操作.看起来你vis.DataSet每次都必须实际创建一个全新的并添加原始数据,然后添加新数据,然后this.setState( { graphData: newGraphData, ... } )

最终,这可能是"纯粹"和正确的方式来做到这一点.

所有这一切,以及一个大的YMMV警告 - 因为没有明显的方法将vis.DataSets视为不可变的,你可以选择第一个选项.

在文档中采取警告的第一部分:

之后调用setState()可能会替换您所做的突变

在那种情况下会发生什么?没什么,因为你所在州的实际物体是可变的,它只是永远的一个参考.如果React'替换它',它将只是替换它自己.换句话说,只要您从不使用全新的DataSet调用setState,就不会在意外的时间将其替换为意外的内容.

这里的一个大问题是,调用forceUpdate会强制重新渲染,这可能会很慢.但是,无论如何,当你调用该函数时,无论如何你都希望它能够重新渲染,所以......实际上你说你可能还好:)