Phát Nguyễn
Phát Nguyễn

Reputation: 185

using custom hook make re-render every time

I create a custom hook take redux variable isLoading, can change isLoading true or false. I import useLoading hook in my component. But when trigger dispatch, my component always re-render and i don't understand why. My demo is very easy here https://codesandbox.io/s/use-custom-hook-loading-oqn8e . Can you explain me why my component always re-render and suggest me to fix it. Thanks a lot.

Upvotes: 0

Views: 2616

Answers (2)

Drew Reese
Drew Reese

Reputation: 202836

Issue:

Basically the react framework can render the component nearly any number of times during the render phase to compute a diff to see what needs to be flushed to the DOM during the commit phase. Your console log is in the function body, so it is executed each time react is computing this diff.

enter image description here

"Render phase" ...May be paused, aborted, or restarted by React.

Solution:

Try using an effect to log anything as it is guaranteed to run once per render cycle (render + commit). Here you'll see only a single log per update/call to setLoading.

function Main() {
  useEffect(() => {
    console.log("Main re-render");
  })
  const [, setLoading] = useLoading();
  return (
    <div>
      <h3>Main</h3>
      <button onClick={() => setLoading(true)}>Start Loading</button>
      <button onClick={() => setLoading(false)}>End Loading</button>
    </div>
  );
}

Upvotes: 1

Nicky McCurdy
Nicky McCurdy

Reputation: 19554

The component is rerendering because its state and context are updating. This component rerenders quickly and React still diffs against the DOM to only write what's changed, so it's not an issue.

Additionally, you shouldn't copy Redux store state to React state like this, it's likely that the loading state in useLoading will become out of date. Instead, use useSelector directly without useState and just dispatch the event to set it. https://codesandbox.io/s/use-custom-hook-loading-w4pc0?file=/src/hooks/loading.js

Upvotes: 0

Related Questions