【问题标题】:React renders based on state change but not on prop change?基于状态变化而不是道具变化的反应渲染?
【发布时间】:2021-10-22 06:09:36
【问题描述】:

我有这个问题的原因是我看不到 React 如何根据 prop 更改进行渲染。

在每条纤程上,beginWork 会渲染纤程,如果有任何状态更改,它将标记更改。如果没有,它可以bailoutOnAlreadyFinishedWork 克隆光纤。在执行此操作时,它reconcileChildren 以便我们知道下一个工作单元是什么。在reconcileChildren 期间,在我看来,每个元素的pendingProps 都是直接使用的。

问题是我看不到道具比较浅的时候。我只在React.memo 和shallowEqual 中看到我期望的代码,然后通过文档https://reactjs.org/docs/react-api.html#reactmemo 确认。

那么默认情况下不浅检查道具的地方是什么?这是否意味着只要有渲染,它就会携带道具作为新版本?

如果有人知道答案,谢谢。

【问题讨论】:

    标签: javascript reactjs fibers


    【解决方案1】:

    其实我在这篇文章中找到了答案,https://medium.com/takeaway-tech/a-deep-dive-into-pure-component-and-react-memo-and-why-do-we-need-them-ae99dce6a33c。

    它坚定地说

    记住:在 React 中,props 是不可变的对象。

    除非使用React.memo,否则道具会一直渲染!!!

    在beginWork 下,React 会在进入新渲染之前比较道具。这是源代码

    function beginWork(current, workInProgress, renderLanes) {
      ...
      if (current !== null) {
        var oldProps = current.memoizedProps;
        var newProps = workInProgress.pendingProps;
    
        if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
         workInProgress.type !== current.type )) {
          // If props or context changed, mark the fiber as having performed work.
          // This may be unset if the props are determined to be equal later (memo).
          didReceiveUpdate = true;
    
    

    但是oldProps !== newProps 并没有进行浅层检查,而是类似于object.is。对于道具,{} !== {} 除非它是克隆副本。因此在我看来,props 并没有像 React 所宣传的那样实现 :)

    当然,如果没有 state 变化,它甚至不会进入 prop 变化。所以也许只要我们确保正确比较状态,它就会转化为正确的渲染?我不知道这是否是正确的理性。

    【讨论】:

    • 我就是这么说的
    【解决方案2】:

    是的,你是对的。如果父状态被更新,无论是 redux 状态还是钩子,它都会重新渲染它的所有组件。但是有一个案例。假设您以仅在更改道具时才会重新渲染的方式实现您的孩子。然后即使父母重新渲染它的所有孩子,孩子也不会重新渲染自己。 react中的这个过程称为memoization。但是是的,如果父状态更新,它将重新渲染它的所有子状态

    参考 - https://reactjs.org/docs/react-api.html#reactmemo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-25
      • 2019-03-07
      • 2023-02-03
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      相关资源
      最近更新 更多