react重新渲染_使用香草钩子React渲染和重新渲染故障

react重新渲染

Anyone who’s worked on react long enough will realize that the cost of rendering the virtual DOM on seemingly unrelated components adds up. So the question is, when do you need to optimize, and what’s a good style to start with?

任何进行了足够长时间的响应的人都会意识到,在看似无关的组件上渲染虚拟DOM的成本加起来了。 因此,问题是,什么时候需要优化,什么是良好的开始?

Note: we will not be looking at real DOM costs, we are assuming React is smart about these, the best optimization will probably be time slicing.

注意:我们不会考虑实际的DOM成本,我们假设React在这些方面很聪明,最好的优化可能是时间分片。

All details were worked out by playing around in a dummy create react app repo here: https://github.com/ayroblu/render-count (warning not pretty)

所有详细信息都通过在此处创建一个虚拟的create react应用程序仓库来解决: https//github.com/ayroblu/render-count (警告不太漂亮)

我们所知道的 (What we know)

  1. The virtual DOM is a tree, this means that re-renders will cause all naive child nodes to re-render, but not their sibling and parent nodes. This makes sense because we do data transfer in this way with props.

    虚拟DOM是一棵树,这意味着重新渲染将导致所有朴素的子节点(而不是其同级节点和父节点)被重新渲染。 这是有道理的,因为我们使用道具以这种方式进行数据传输。
  2. children is just another prop, so nesting nodes is the same as passing them in props.

    儿童只是另一个道具,因此嵌套节点与在道具中传递它们相同。

  3. context change will cause all nodes that use this context with useContext to change.

    语境的变化会导致使用这种背景下useContext改变所有节点。

树木和记忆 (Trees and memoisation)

So what we know from 1. is that any state orchestration in parent nodes will be expensive. One option here is to wrap all functions in React.memo, and of course make sure you memoise all props like objects and functions.

因此,从1中我们知道,父节点中的任何状态编排都是昂贵的。 这里的一种选择是将所有函数包装在React.memo中,当然要确保记住所有道具,例如对象和函数。

儿童和参考道具 (Children and reference props)

What we know from 2. is that composition costs us render cycles, because JSX creates new objects which creates a new reference, which will trigger re-renders, even with React.memo. Note however that basic child components will not re-render in this case

从2中我们知道,合成花费了渲染周期,因为JSX创建了新对象,该对象创建了新引用,即使使用React.memo也会触发重新渲染。 但是请注意,在这种情况下,基本子组件不会重新渲染

<div onClick={reRenderMe}> // onClick to force re-render
  <FirstComp> // This one will also re-render because children
    <SecondComp /> // This one will not
  </FirstComp>
</div>

语境(Context)

What we know from 3. is that useContext and more generally, global state becomes more expensive here. The ways to mitigate this are using multiple narrower context’s, and/or to adopt a redux pattern with “connect” style components.

从3.我们知道的是useContext以及更一般的说,全局状态在这里变得更加昂贵。 减轻这种情况的方法是使用多个较窄的上下文,和/或采用带有“连接”样式组件的redux模式。

const ConnectedComp = React.memo(() => {
  const { state, dispatch } = React.useContext(context);
  return (
    <Comp
      value={state.value1}
      onClick={React.useCallback(
        () => dispatch(actions.myAction({ value1: state.value1 + 1 })),
        [dispatch, state.value1]
      )}
    />
  );
});

This way, all the connected components will always re-render, but the child components will only change when (in this case) value1 changes. Of course you can write or use an actual connect higher order component for this, this code just outlines the principle.

这样,所有连接的组件将始终重新呈现,但是子组件仅在(在这种情况下) value1更改时更改。 当然,您可以为此编写或使用实际的连接高阶组件,此代码仅概述了原理。

概要 (Summary)

  1. Use React.memo everywhere. As has been highlighted by other blog posts, this may not necessarily improve performance in all cases, however the downside is relatively low, and the upside could be relatively high, especially when you use fancy third party components. If you want to be optimal, test and measure the difference in speed, but this is more effort than it’s worth, it’s a more sensible default than using it nowhere.

    随处使用React.memo 。 正如其他博客文章所强调的那样,这不一定在所有情况下都能提高性能,但是不利因素相对较低,而不利因素可能相对较高,尤其是在使用高级第三方组件的情况下。 如果您想获得最佳效果,请测试并测量速度差异,但这比其应付出的努力还要多,这是比不使用它更明智的默认设置。

  2. Beware objects, including composition of nodes. Memoise where reasonable here.

    当心对象,包括节点的组成。 记住这里合理的地方。
  3. If using a global state, consider using multiple context’s in lieu of the combineReducers redux pattern. Also consider using a connect pattern to stop unnecessary re-renders.

    如果使用全局状态,请考虑使用多个上下文代替combindReducers的redux模式。 还可以考虑使用连接模式来停止不必要的重新渲染。

翻译自: https://medium.com/@benlu/react-rendering-and-re-rendering-breakdown-with-vanilla-hooks-3242b7ebd1c5

react重新渲染

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值