reactjs - 带回调的forceUpdate() 与 this.setState()

标签 reactjs

这样做的原因是在处理具有自己功能的状态变量时。我能想到的有两种方法。一种是通过调用状态函数直接改变 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));
  }

最佳答案

你绝对不应该改变 this.state 或其中的任何内容。来自 React Component API docs :

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate(), calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders.

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

最终这可能是“纯粹”且正确的方法。

尽管如此,但还有一个重要的 YMMV 警告 - 由于没有明显的方法将 vis.DataSet 视为不可变,您可能可以选择第一个选项。

查看文档中警告的第一部分:

calling setState() afterwards may replace the mutation you made

这种情况下会发生什么?没什么,因为你的状态中的实际对象是可变的,它永远只是一个引用。如果 React“替换它”,它只是用它自己替换它。换句话说,只要您从未使用全新的 DataSet 调用 setState,它就不会在意外的时间被意外的内容替换。

这里的大问题是调用forceUpdate将强制重新渲染,这可能会很慢。但听起来你希望它在调用该函数时无论如何都重新渲染,所以......务实地说你可能没问题:)

关于reactjs - 带回调的forceUpdate() 与 this.setState(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35284105/

相关文章:

javascript - 通过调用shopify api创建新产品

javascript - Meteor 和 React 的双向数据绑定(bind)

javascript - 在 Material UI 的 <ListItem> 中的primaryText左侧添加一个图标

javascript - 在 react 中将数据添加到字典

css - 使用 reactstrap 将 Bootstrap Studio 渲染导入 React 时出现问题

javascript - mobx中如何实现数组的浅拷贝

javascript - 在 reactjs 中为 tensorflowjs 加载 model.json 不起作用

javascript - 如何在 ReactJS 中验证完成后重定向页面

javascript - 在 auth0 中获取 accessToken

javascript - 具有动态代码分割的自动 vendor block