Reputation: 185
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
Reputation: 202836
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.
"Render phase" ...May be paused, aborted, or restarted by React.
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
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