一个React更新问题解析

78 阅读1分钟
const B = ({ children }) => {
  console.log('render B');
  const [count, setCount] = React.useState(0);
  return (
    <div>
      <div onClick={() => setCount(count + 1)}>B</div>
      {children}
    </div>
  ); 
}

const C = ({ children }) => {
  console.log('render C');
  return <div>C</div>;
}

const D = ({ children }) => {
  console.log('render D');
  return <div>D</div>;
}

const App = () => {
  return (
    <B>
      <C/>
      <D />
    </B>
  )
}
const B = ({ children }) => {
  console.log('render B');
  const [count, setCount] = React.useState(0);
  return (
    <div>
      <div onClick={() => setCount(count + 1)}>B</div>
      <>
        <C/>
        <D />
      </>
    </div>
  ); 
}

const App = () => {
  return (
    <B></B>
  )
}

20220721173906

上面两段代码渲染后的fiber结构是一样的, 但是点击B, console.log打印的结果却不相同.

第一段代码结果:

render B

第二段代码结果:

render B
render C
render D

第一段代码, 组件C,D没有重新渲染.

我们将目标放在6:Fragment这个节点上, 当处理这个节点时, 它的props只有一个children, 为[<C/>, <D/>]. 第一段代码中, Fragment节点的children来自App, App没有运行, 所以children与前一次渲染是一样的, 也就是oldProps === newProps. 第二段代码中, Fragment节点的children来自B, B运行, 所以产生了新的对象, oldProps !== newProps.

这就是它们的不同。