React parent pass children 将在没有 state/props 更改的情况下触发重新渲染

React parent pass children will trigger rerender without state/props change

当我有一些 children(HTML dom) 作为 child 组件的道具并在 parent 中进行控制时,我发现会触发重新渲染!

为什么 React parent 传递 children 会在没有 state/props 更改的情况下触发重新渲染?

如何避免?检查以下内容。


const InsideChild = React.memo(({children}) => {
  const countRef = useRef(0)
  countRef.current += 1

  return (
    <div>render count: {countRef.current} {children}</div>
  )
})
                        
const OutsideParent = () => {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <div>
        Test1:
        <InsideChild />
      </div>
      <div>
         Test2:
         <InsideChild>
           <p>children as html dom will not trigger rerender.</p>
         </InsideChild>
      </div>
    </div>
  )
}

作为示例代码,Test1 不会触发重新渲染,Test2 会。可以避免吗?

此处有更多详细信息和工作示例:

https://codepen.io/sky790312/pen/QWqygxQ

当您发送 html 时,React.memo 不起作用,因为您 children 是 object在这种情况下,您可以比较它的唯一方法是进行深度比较或其他方式。

你可以在你的备忘录中添加一个比较器功能,在你发送一个 html.

的情况下比较 object 的内部属性

例子中我只是检查props是不是object然后比较里面的object希望对你有帮助

const comparisonFn = (prevProps, nextProps) => { 
  if(typeof prevProps?.children === 'object') {
    return prevProps?.children.props.children == 
      nextProps?.children.props.children
  } else {
    return prevProps?.children === nextProps?.children;
  }
}

const InsideChild = React.memo(({children}) => {
  const countRef = useRef(0)
  countRef.current += 1

  return (
    <div>render count: {countRef.current} {children}</div>
  )
}, comparisonFn)