【问题标题】:React parent pass children will trigger rerender without state/props changeReact parent pass children 将触发重新渲染而不更改 state/props
【发布时间】:2022-01-11 19:06:29
【问题描述】:

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

为什么 React parent pass 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

【问题讨论】:

标签: reactjs react-hooks rerender


【解决方案1】:

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

您可以在备忘录中添加比较器功能,并在您发送 html 的情况下比较对象的内部道具。

在示例中我只是检查道具是否是一个对象,然后比较里面的对象,希望对你有帮助

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)

【讨论】:

  • 知道了,我知道现在发生了什么。谢谢。我很少看到这样的项目句柄,我应该处理吗?
猜你喜欢
  • 2016-12-30
  • 2020-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 2020-07-13
相关资源
最近更新 更多