为什么React.memo不使用`props.Children'的财产?

发布于 2025-02-01 22:34:01 字数 1388 浏览 2 评论 0原文

我正在尝试在react.memo()中将子组件(“ box”)包裹起来,以避免当父组件从状态更改中重新呈现时,避免了不必要的重新订阅者。但这与props.Children属性不起作用。当我在不使用props.Children的情况下再次尝试时,它确实有效!但为什么?如果不是Memo,我该如何使用构图和props.Cops.Cops.Cops.Cops.Cops.Cops.Cops.Cops.Cops.copss.?我该如何实现?

(1)传递组件示例(工作):&lt; box title =“我是一个框” /&gt; < /code>

(2)传递组件示例(无效):&lt ; box&gt; &lt; h1&gt; i是一个盒子&lt;/h1&gt; &lt;/box&gt;

///

工作示例(1):

导出默认备忘录(function box(props){ 返回 ( &lt; div className ='box'&gt;&lt; h1&gt; {props.title}&lt;/h1&gt;&gt;&lt;/div&gt; ) });

父级组件:

不工作示例(2):

导出默认备忘录(功能框(props){ 返回 ( &lt; div className ='box'&gt; {props.children}&lt;/div&gt; ) });

父元组件:

I'm trying to wrap a subcomponent ("Box") in React.memo() to avoid the unnecessary re-renders of it when the parent component re-renders from state change. But this didn't work with props.children property. When I tried again without using props.children, it did work! But why? And how can i achieve this using composition and props.children property if not with memo ?

(1) Passing the component example (worked): <Box title="i am a box" />

(2) Passing the component example (didn't work): <Box> <h1>I am a box</h1> </Box>

///

Working example (1):

export default memo (function Box(props) {
return (
<div className='box'><h1>{props.title}</h1></div>
)
} );

Box Component with inheritance

Parent component:
enter image description here

Not working example (2):

export default memo (function Box(props) {
return (
<div className='box'>{props.children}</div>
)
} );

Box Component with composition

Parent component:
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

耳钉梦 2025-02-08 22:34:01

我可以解释一下。

  1. 备忘录会累积光,没有深刻的构成。
  2. 当您经过孩子的绳子时,备忘录将与孩子一起工作。
  3. 如果您通过一些元素或组件,则Props.Childrens将包含带有传递元素的参考的数组。每个渲染将收到一个新数组。数组可能具有相同的内容,但是对数组的引用将有所不同。这些是不同的阵列,备忘录不会进行深入的比较。它不会比较数组,对象的内容,而是仅比较对它们的参考。

基于上述内容,为什么这在您的示例上不起作用。您小时候正在传递“ H1”元素。在您的子部分中,有一个“ H1”元素的数组。对于父母的每个渲染,将会出现一个新的阵列。是的,它将是一个具有相同内容的数组,但不是相同的数组,而不是相同的引用。备忘录没有进行深入检查。

下面有两个示例,带有字符串和元素。

// if you pass string as children, memo will be work

const MemoizedChildComponent = memo(({children}) => {
  console.log('render', children) // only one time render, children: "string"
  return <div>children</div>
})

const App = () => {
  const [count, setCount] = useState(1)

  const handleCountIncrement = () => {
    setCount(count + 1)
  }

  return <div>
    <button onClick={handleCountIncrement}>increase</button>
    <MemoizedChildComponent>string</MemoizedChildComponent> // pass simple string
  </div>
}

但是,如果您不想放弃元素并想记住它们怎么办?

我建议使用Usememo Hook回忆过世的孩子。

我不会说那很好。但是,如果您的目标是记住孩子,这将有所帮助。您无法用备忘录解决这个问题。没有深入的比较,因此备忘录和孩子存在问题。不要忘记在usememo中指定依赖项,示例中没有一个,因此依赖项数组为空。

const MemoizedChildComponent = memo(({children}) => {
  console.log('render', children) // only one time render, because it children memoized in parent component inside useMemo hook. children: [object, object, object]
  return <div>children</div>
})

const App = () => {
  const [count, setCount] = useState(1)

  const handleCountIncrement = () => {
    setCount(count + 1)
  }

  const memoizedChildren = useMemo(() => [
    <p key="1">asd</p>,
    <p key="2">asd</p>,
    <p key="3">asd</p>
  ], [])

  return <div>
    <button onClick={handleCountIncrement}>increase</button>
    <MemoizedChildComponent>{memoizedChildren}</MemoizedChildComponent>
  </div>
}

I can explain this.

  1. Memo does light comprasion, no deeply comprasion.
  2. When you pass string in children, then memo will be work with children.
  3. If you pass some elements or components, props.childrens will be contain array with refs on passed elements. Each render will receive a new array. An array may have the same content, but the reference to the array will be different. These are different arrays, memo doesn't do deep comparisons. It does not compare the contents of arrays, objects, but only references to them.

Based on the above, why doesn't this work on your example. You are passing the "h1" element as children. In your child component comes an array with one "h1" element. And for each render of the parent, a new array will come. Yes, it will be an array with the same content, but it is not the same array, not the same reference. Memo does not do deep checks.

Below two examples, with string and elements.

// if you pass string as children, memo will be work

const MemoizedChildComponent = memo(({children}) => {
  console.log('render', children) // only one time render, children: "string"
  return <div>children</div>
})

const App = () => {
  const [count, setCount] = useState(1)

  const handleCountIncrement = () => {
    setCount(count + 1)
  }

  return <div>
    <button onClick={handleCountIncrement}>increase</button>
    <MemoizedChildComponent>string</MemoizedChildComponent> // pass simple string
  </div>
}

But what if you don’t want to abandon the elements and want to memoize them?

I suggest use useMemo hook for memoize passed children.

I won't say that's good. But it will help if your goal is to memoize children. You can't solve this problem with memo. There is no deep comparison, so there is a problem with memo and children. Don't forget to specify dependencies in useMemo, there are none in the example, so the dependencies array is empty.

const MemoizedChildComponent = memo(({children}) => {
  console.log('render', children) // only one time render, because it children memoized in parent component inside useMemo hook. children: [object, object, object]
  return <div>children</div>
})

const App = () => {
  const [count, setCount] = useState(1)

  const handleCountIncrement = () => {
    setCount(count + 1)
  }

  const memoizedChildren = useMemo(() => [
    <p key="1">asd</p>,
    <p key="2">asd</p>,
    <p key="3">asd</p>
  ], [])

  return <div>
    <button onClick={handleCountIncrement}>increase</button>
    <MemoizedChildComponent>{memoizedChildren}</MemoizedChildComponent>
  </div>
}
日久见人心 2025-02-08 22:34:01

该组件的孩子实际上来自父母。当父级重新租赁时,它会重新计算所有内容,并触发返回语句。该返回声明中的所有内容均已重新创建,并要求所有孩子重新渲染。

其中一些可能是记忆的组件,这将决定是否应根据道具重新渲染。但是,当您将孩子转到该组件时,对于父母的每一个重新渲染,您都会将新的孩子的新实例发送到该回忆的组成部分。因此,它使其重新渲染。

Children of the component are actually coming from its parent. When parent re-renders, it recalculates everything and the return statement is triggered. Everything in that return statement is re-created and all the children are asked to re-render.

Some of them might be memoized components, which will decide if they should re-render based on the props. However, when you pass children to that component, for every re-render of the parent, you send a new instance of children to that memoized component. Hence, it causes it to re-render.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文