簡體   English   中英

如何將 React.memo 與包含子項的組件一起使用

[英]how to use React.memo with a Component contains children

需要幫助~

我有兩個組件,我用 React.memo 包裹了 Parent:

孩子

const Child = ()=> <div>I'm Child</div

export default Child

家長

const Parent = (props)=> <div>{props.children}</div>

export default React.memo(Parent)

在應用程序中使用:

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

  return(
    <div>
      <button onClick={()=>setCount(count+1)}></button>

      <Parent>
        <Child></Child>
      </Parent>
    </div>
  )
}

點擊按鈕,結果:

父組件將重新渲染,因此備忘錄不起作用,因為它的子組件是一個函數組件

那么,如何防止重新渲染?

我知道用useMemo解決的方法,但是又丑又不友好,大家有更好的想法嗎?

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

  const children = useMemo(()=><Child></Child>,[])

  return(
    <div>
      <button onClick={()=>setCount(count+1)}></button>

      <Parent>
        {children}
      </Parent>
    </div>
  )
}

React.memo包裹你的<Child />

const Child = ()=> {
  console.log('render') // fires only once - on initial render
  return <div>I'm Child</div>
}

const MChild = React.memo(Child);
const Parent = (props)=> <div>{props.children}</div>
const MParent = React.memo(Parent)

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

  return(
    <div>
      <button onClick={()=>setCount(count+1)}>increment {count}</button>
      <MParent>
        <MChild></MChild>
      </MParent>
    </div>
  )
}

render(<App />, document.getElementById('root'));
const children = useMemo(()=><Child></Child>,[])

是最簡單的方法。 使用memo(Child)不起作用,因為每當您調用<Child />時,jsx 實際上都會返回一個新對象。 React.memo默認只使用簡單的淺比較,所以真的沒有其他直接的方法來解決它。 您可以創建自己的函數,最終支持子項並將其傳遞給React.memo(MyComp, myChildrenAwareEqual)

<Parent><Child/></Parent>到一個單獨的組件中,並記住組件:

const Family = memo(() => <Parent><Child/></Parent>);

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

  return (
    <>
      <button onClick={() => setCount(count => count + 1)}>{count}</button>
      <Family />
    </>
  )
}

演示

const Memo = React.memo(({ children, value }) => {
  return children
}, (prev, next) => prev.value === next.value)

然后使用它

function Title() {
  const [count, setCount] = useState(0)
  const onClick = () => {
    setCount(c => c + 1)
  }

  const a = ''

  return (
    <>
      <div onClick={onClick}>{count}</div>
      <Memo value={a}>
        <Child>
          <Nothing2 a={a} />
        </Child>
      </Memo>
    </>
  )
}

a改變時,Child 渲染,否則它會與之前的渲染一起跳出。

我在我的博客中概述了它背后的理性, https://javascript.plainenglish.io/can-usememo-skip-a-child-render-94e61f5ad981

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM