博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactJS-每次调用“ setState”时都会调用渲染吗?
阅读量:2384 次
发布时间:2019-05-10

本文共 6463 字,大约阅读时间需要 21 分钟。

本文翻译自:

Does React re-render all components and sub components every time setState is called? 每当调用setState React是否会重新渲染所有组件和子组件?

If so, why? 如果是这样,为什么? I thought the idea was that React only rendered as little as needed - when state changed. 我以为这个想法是,当状态改变时,React只渲染所需的内容。

In the following simple example, both classes render again when the text is clicked, despite the fact that the state doesn't change on subsequent clicks, as the onClick handler always sets the state to the same value: 在下面的简单示例中,尽管状态在以后的单击中不会改变,但两个类在单击文本时都再次呈现,因为onClick处理程序始终将state设置为相同的值:

this.setState({'test':'me'});

I would've expected that renders would only happen if state data had changed. 我曾希望只有在state数据已更改的情况state才会进行渲染。

Here's the code of the example, , and embedded snippet: 这是示例代码,例如和嵌入式代码段:

var TimeInChild = React.createClass({ render: function() { var t = new Date().getTime(); return ( 

Time in child:{t}

); } }); var Main = React.createClass({ onTest: function() { this.setState({'test':'me'}); }, render: function() { var currentTime = new Date().getTime(); return (

Time in main:{currentTime}

Click me to update time

); } }); ReactDOM.render(
, document.body);
 

[1]: http://jsfiddle.net/fp2tncmb/2/

#1楼

参考:


#2楼

Does React re-render all components and sub components every time setState is called? 每当调用setState时,React是否会重新渲染所有组件和子组件?

By default - yes. 默认情况下-是。

There is a method boolean shouldComponentUpdate(object nextProps, object nextState) , each component has this method and it's responsible to determine "should component update (run render function)?" 有一个方法boolean shouldComponentUpdate(object nextProps,object nextState) ,每个组件都有此方法,它负责确定“组件应该更新(运行渲染功能)吗?”。 every time you change state or pass new props from parent component. 每次更改状态或从父组件传递新的道具时

You can write your own implementation of shouldComponentUpdate method for your component, but default implementation always returns true - meaning always re-run render function. 您可以为组件编写自己的shouldComponentUpdate方法实现,但是默认实现始终返回true-意味着始终重新运行渲染函数。

Quote from official docs 引用官方文档

By default, shouldComponentUpdate always returns true to prevent subtle bugs when state is mutated in place, but if you are careful to always treat state as immutable and to read only from props and state in render() then you can override shouldComponentUpdate with an implementation that compares the old props and state to their replacements. 默认情况下,shouldComponentUpdate始终返回true,以防止状态发生适当变化时产生细微的错误,但是如果您始终将状态视为不可变并仅从props和render()中的状态读取状态,则可以使用实现将旧的道具和状态与其替换进行比较。

Next part of your question: 问题的下一部分:

If so, why? 如果是这样,为什么? I thought the idea was that React only rendered as little as needed - when state changed. 我以为这个想法是,当状态改变时,React只渲染所需的内容。

There are two steps of what we may call "render": 我们可以将“渲染”分为两个步骤:

  1. Virtual DOM render: when render method is called it returns a new virtual dom structure of the component. 虚拟DOM渲染:调用render方法时,它将返回组件的新虚拟dom结构。 As I mentioned before, this render method is called always when you call setState() , because shouldComponentUpdate always returns true by default. 如前所述,此渲染方法总是在您调用setState()时调用,因为默认情况下shouldComponentUpdate始终返回true。 So, by default, there is no optimization here in React. 因此,默认情况下,React中没有优化。

  2. Native DOM render: React changes real DOM nodes in your browser only if they were changed in the Virtual DOM and as little as needed - this is that great React's feature which optimizes real DOM mutation and makes React fast. 原生DOM渲染:仅当在虚拟DOM中更改了真实DOM节点时,React才更改浏览器中的真实DOM节点,并且需要的次数很少-这就是React的一项出色功能,它可以优化真实DOM变异并使其快速运行。


#3楼

No, React doesn't render everything when state changes. 不,状态更改时,React不会呈现所有内容。

  • Whenever a component is dirty (its state changed), that component and its children are re-rendered. 每当组件变脏(状态更改)时,都会重新渲染该组件及其子代。 This, to some extent, is to re-render as little as possible. 在某种程度上,这是尽可能少地重新渲染。 The only time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. 唯一不调用render的时候就是将某个分支移到另一个根,从理论上讲,我们不需要重新渲染任何东西。 In your example, TimeInChild is a child component of Main , so it also gets re-rendered when the state of Main changes. 在您的示例中, TimeInChildMain的子组件,因此当Main的状态更改时,它也会重新呈现。

  • React doesn't compare state data. React不比较状态数据。 When setState is called, it marks the component as dirty (which means it needs to be re-rendered). 调用setState ,它将组件标记为脏(这意味着它需要重新呈现)。 The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (aka diffing between the Virtual DOM tree and document's DOM tree). 需要注意的重要一点是,尽管调用了组件的render方法,但是仅当输出与当前DOM树不同时(也就是在虚拟DOM树和文档的DOM树之间进行区分),才更新实际DOM。 In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from document's DOM, hence why the HTML is updated. 在您的示例中,即使state数据没有更改,上次更改的时间也发生了更改,从而使Virtual DOM与文档的DOM有所不同,因此,为什么要更新HTML。


#4楼

Yes. 是。 It calls the render() method every time we call setState instead when "shouldComponentUpdate" returns false. 每当“ shouldComponentUpdate”返回false时,它将每次调用setState时调用render()方法。


#5楼

Even though it's stated in many of the other answers here, the component should either: 即使在这里的许多其他答案中都已说明,该组件也应该:

  • implement shouldComponentUpdate to render only when state or properties change 实现shouldComponentUpdate以仅在状态或属性更改时呈现

  • switch to extending a , which already implements a shouldComponentUpdate method internally for shallow comparisons. 切换到扩展 ,该方法已经在内部实现了shouldComponentUpdate方法以进行浅表比较。

Here's an example that uses shouldComponentUpdate , which works only for this simple use case and demonstration purposes. 这是一个使用shouldComponentUpdate的示例,该示例仅用于此简单用例和演示目的。 When this is used, the component no longer re-renders itself on each click, and is rendered when first displayed, and after it's been clicked once. 使用此功能后,组件将不再在每次单击时重新呈现其自身,而是在首次显示时以及单击一次后呈现。

var TimeInChild = React.createClass({ render: function() { var t = new Date().getTime(); return ( 

Time in child:{t}

); } }); var Main = React.createClass({ onTest: function() { this.setState({'test':'me'}); }, shouldComponentUpdate: function(nextProps, nextState) { if (this.state == null) return true; if (this.state.test == nextState.test) return false; return true; }, render: function() { var currentTime = new Date().getTime(); return (

Time in main:{currentTime}

Click me to update time

); } }); ReactDOM.render(
, document.body);
 

转载地址:http://wfexb.baihongyu.com/

你可能感兴趣的文章
html5 drawImage 不显示问题
查看>>
node.js web应用基本框架
查看>>
node.js站点备份
查看>>
node.js文件上传处理
查看>>
nodejs常用工具util
查看>>
js 模版引擎jade使用语法
查看>>
node.js express 运行环境 NODE_ENV
查看>>
magento修改页面标题的3种方法
查看>>
图解HTTPS
查看>>
html5鼠标滚轮事件mousewheel使用
查看>>
js遍历对象属性和值
查看>>
js 区分鼠标左右键
查看>>
[SEO基础知识] 对于Title标签中常见的分隔符的介绍
查看>>
vim同时(取消)注释多行文本
查看>>
apache mod_auth设置访问用户登录
查看>>
magento widget开发使用教程
查看>>
magento开发数据库eav模型实例
查看>>
magento Block缓存实例-给AW_Blog插件添加缓存
查看>>
php生成二维码
查看>>
Web通信之:长轮询(long-polling)
查看>>