最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Avoid re-render with `useCallback` - Stack Overflow

programmeradmin3浏览0评论

I am trying to figure out why when I click on a specific ponent its sibling it will render too

function CountButton({increment, count, number}) {
  console.log(`Render CountButton ${number}`)

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

function DualCounter() {
  const [count1, setCount1] = React.useState(0)
  const increment1 = React.useCallback(() => setCount1(c => c + 1), [])
  const [count2, setCount2] = React.useState(0)
  const increment2 = React.useCallback(() => setCount2(c => c + 1), [])
  console.log('Render DualCounter')

  return (
    <>
      <CountButton count={count1} increment={increment1} number={1} />
      <CountButton count={count2} increment={increment2} number={2} />
    </>
  )
}

I use useCallback and I pass theses function to use avoid that in any render the functions reference will be a different reference.

I am trying to figure out why when I click on a specific ponent its sibling it will render too

function CountButton({increment, count, number}) {
  console.log(`Render CountButton ${number}`)

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

function DualCounter() {
  const [count1, setCount1] = React.useState(0)
  const increment1 = React.useCallback(() => setCount1(c => c + 1), [])
  const [count2, setCount2] = React.useState(0)
  const increment2 = React.useCallback(() => setCount2(c => c + 1), [])
  console.log('Render DualCounter')

  return (
    <>
      <CountButton count={count1} increment={increment1} number={1} />
      <CountButton count={count2} increment={increment2} number={2} />
    </>
  )
}

I use useCallback and I pass theses function to use avoid that in any render the functions reference will be a different reference.

Share Improve this question asked Feb 21, 2021 at 19:22 Ismael RodriguezIsmael Rodriguez 3394 silver badges10 bronze badges 2
  • Because you pass in count1 / count2 as a prop as well. This props is changed so the ponent is re-rendered – Kevin Commented Feb 21, 2021 at 19:26
  • If DualCounter is re-renders, it's children will render too.. You can use memo – lissettdm Commented Feb 21, 2021 at 19:29
Add a ment  | 

1 Answer 1

Reset to default 5

You are seeing a re-render on the sibling <CountButton /> ponent, because each time you hit the button to update the counter, you are actually updating a state value in the parent ponent <DualCounter />, which causes a re-render on that ponent as well.

And since DualCounter is re-rendered, child ponents will re-render as well, which in this case includes both <CountButton /> elements.

A solution to prevent this, would be wrapping CountButton ponent with React.memo(). This will prevent a re-render on a ponent that didn't have any change on the props values.

Example below:

function CountButton({increment, count, number}) {
  console.log(`Render CountButton ${number}`)

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

const CountButtonMemo = React.memo(CountButton)

function DualCounter() {
  const [count1, setCount1] = React.useState(0)
  const increment1 = React.useCallback(() => setCount1(c => c + 1), [])
  const [count2, setCount2] = React.useState(0)
  const increment2 = React.useCallback(() => setCount2(c => c + 1), [])
  console.log('Render DualCounter')

  return (
    <>
      <CountButtonMemo count={count1} increment={increment1} number={1} />
      <CountButtonMemo count={count2} increment={increment2} number={2} />
    </>
  )

Another solution would be not updating the DualCounter state on each change caused by events on your CountButton ponents, which will stop triggering unwanted re-renders on their siblings. You could handle the state directly on each CountButton ponent if this made sense for your app.

Alternatively, you could use a React state management tool, such as Redux, which also solves exactly this issue, by taking charge of delegating the state of your app separated from your ponents themselves.

发布评论

评论列表(0)

  1. 暂无评论