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

2024-01-06

原因是在处理时state具有自己功能的变量。我能想到的有两种方法。一是变异this.state直接(嗯,有点,我知道这是不鼓励的)通过调用状态函数,然后调用forceUpdate()并处理由此带来的后果。另外就是做回调函数。哪个是正确的方法?

这是我正在谈论的一个例子。我正在与Vis.js http://visjs.org,并且它们的 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 组件 API 文档 https://facebook.github.io/react/docs/component-api.html#setstate:

永远不要直接改变 this.state,因为之后调用 setState() 可能会替换您所做的改变。将 this.state 视为不可变的。

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

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

setState() 总是会触发重新渲染,除非在 shouldComponentUpdate() 中实现了条件渲染逻辑。如果使用可变对象并且逻辑无法在 shouldComponentUpdate() 中实现,则仅在新状态与先前状态不同时调用 setState() 将避免不必要的重新渲染。

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

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

话虽如此,但还有一个 YMMV 警告——因为没有明显的治疗方法vis.DataSet由于它是不可变的,您可能可以选择第一个选项。

以文档中警告的第一部分为例:

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带回调的forceUpdate() 与 this.setState() 的相关文章

随机推荐

  • 如何在python中获取sqlsoup中模式的列名?

    如何使用Python中的SQLSOUP从模式 表中获取字典中的列名和类型 使用MySQLDB 我可以创建游标并使用cursor description sqlsoup 有类似的东西吗 根据文档 https sqlalchemy readth
  • 您可以更改 GitLab 管道中的代码吗?

    GitLab CI CD 管道是否可以提交代码更改 我想运行一个使用的阶段black https github com psf black每当我推动工作时自动格式化我的代码 gitlab ci yml image python 3 6 st
  • 有没有办法自动避免进入 Visual Studio 中的某些函数?

    我知道 仅启用我的代码 调试选项 但这仅适用于托管代码 我正在寻找一种无需单步执行函数调用的方法 例如 STL 字符串转换运算符 因为函数参数之一中存在从 char 到字符串的隐式转换 我找到了这个博客条目 http blogs msdn
  • 远程服务器上的 Django 教程:如何在我的浏览器中查看?

    我正在开始学习 Django 教程 但遇到了障碍 在我常用的域上创建了示例 mysite 后 我希望能够在我的浏览器中显示它 该教程向我指出http 127 0 0 1 8000 http 127 0 0 1 8000 但是 这是行不通的
  • 如何将 Shell 变量值访问到 Groovy 管道脚本中

    现在我是 Shell Jenkins Groovy pipeline 的新手 我的要求是我正在将文件文本读取到 shell 脚本下的变量中 并且我需要将该变量值从 shell 脚本中传递出来并在 Groovy 脚本中使用 这是我的代码 st
  • 如何在android中创建可变数量的textview

    希望这不是一个坏问题 但是我已经通过 S O 进行了搜索 并且一直没能找到答案 我正在创建一个 Android 应用程序 它本质上是一个闹钟 我希望主要活动显示已创建的所有警报以及有关警报的一些信息 我的问题是如何根据已创建的警报数量创建给
  • TortoiseSVN合并分支到主干

    我知道这个问题已经被问过好几次了 所以我很抱歉再次问这个问题 但我只是想确保我理解不同合并之间的区别 我是这个项目的唯一开发人员 所以我不担心重写其他人的工作 我创建了这个项目的一个分支 因为我即将添加一些新功能 并且如果我需要修复当前代码
  • 用毫秒获取文件的最后修改日期?

    我正在尝试从文件夹中获取某些文件的日期和时间 上次修改 我设法获取日期和小时 分钟 秒 但无法获取毫秒 我已经尝试以所有可能的方式格式化该列 我只得到0毫秒 到目前为止我的代码是 用户选择一个文件夹 该代码在 A 列中显示找到的所有文件名
  • Socket.IO - 无法在 Google Chrome 中加载 XMLHttpRequest

    我试图从在 Chrome 19 0 1048 46 中工作的 socket io 主页获取第一个示例 但出现错误 XMLHttpRequest 无法加载 http localhost 8080 socket io 1 t 133715619
  • 函数 driver.switchTo.frame() 在 Selenium 中不起作用

    当我尝试在 Python 中使用 Selenium 中的 Webdriver 切换到网页上的框架时 它向我显示错误 请在下面找到我的代码 driver switchTo frame frame AttributeError WebDrive
  • Android 原生代码分析

    我正在尝试分析本机 Android 代码 但我得到了 出现以下错误 我正在 Linux 机器上运行代码 tracedmdump 配置文件后处理 痕迹 静态基本块 64525 动态 基本块 87073132 静态指令 412004 动态 说明
  • Windows 批处理,仅选择用户变量

    在环境变量中 我有一个用于用户变量和系统变量的 PATH 变量 在批处理脚本中 为了向用户 PATH 变量附加新的给定路径 我需要选择当前值 不幸的是 PATH 返回用户变量和系统变量的组合 当然 我只想向用户变量添加新的自定义路径值 也没
  • Codeigniter 3.0.0 - 错误 404 页面未找到

    这是我的第一个 php 框架 我的控制器中有一个 php 文件 即 posts php 但是当我尝试运行它 localhost codeigniter index php posts 时 它显示错误 404 应用程序文件夹内的 htacce
  • Azure DevOps 拉取请求线条颜色

    I created a PR and some of lines are marked with red or green colors in newly created file Cannot find what does it mean
  • 如何重新加载 JSF 使用的 ResourceBundles?

    我想通过单击按钮以编程方式重新加载 JSF 使用的 ResourceBundles 类路径中的 ResourceBundles 即 WEB INF classes 由外部应用程序修改 并且我知道修改事件 Try ResourceBundle
  • PHP中的矩阵乘法

    尽管矩阵的顺序应该没问题 但以下代码会抛出异常 这可能是一件我无法注意到的小事 但无法弄清楚
  • Python通过鼠标点击找到最近的乌龟

    我正在使用基于海龟的网格设置创建扫雷风格的游戏 我需要找到网格内最近的单元格并显示位于其下方的图标 无论是炸弹还是数字图标 我不想做到精确 我只需要单击鼠标即可找到网格中最近的单元格 即使单击不是直接在板上 目前 我的代码仅显示板上创建的最
  • 如何读取 Bash 中的任意一个键?

    我可以得到read n 1 KEY获取大多数键 但由多个字符表示的键除外 例如 如果我按向上箭头键 read n 1 echo A A As you can see read only takes the Esc and the A is
  • 使用 Python 加载 CloudFormation YAML

    我有一套YAML我最近转换的 AWS Cloudformation 模板JSON 使用时JSON我能够加载这些模板并使用它们进行转换jinja从中生成一些 Markdown 文档 我正在尝试做同样的事情YAML在Python中 我在 clo
  • 带回调的forceUpdate() 与 this.setState()

    原因是在处理时state具有自己功能的变量 我能想到的有两种方法 一是变异this state直接 嗯 有点 我知道这是不鼓励的 通过调用状态函数 然后调用forceUpdate 并处理由此带来的后果 另外就是做回调函数 哪个是正确的方法