Reputation: 706
I'm a new fan of the React Functional Component. When I read the document and try to do some experiments then I figure out a doubting case.
I have a custom-hook "useAutoIncrement" that has a setInterval which increases the "num" every second. The main component re-render when this interval fires. Then I change setState a fixed number for custom-hook 0. As Expected, the main component wouldn't re-render. We have been good so far :)
Then try to click "button" increment of the event handler in the main component, the main one re-render, and the custom-hook re-render also. But when the interval runs in the first next time to setState value 0, the strange thing happens. The main component and the custom-hook seem to re-render (I place some consolg.log and it shows up), but there is no console.log show up inside the useEffect both main-component and custom-hook.
Take a look at this image, 3 blue-lines. The 1st blue-line is inside the hook-effect interval function. It calls setNum with un-changed value. The main component shouldn't re-render but it seems did. The 2nd and 3rd blue-line print out they re-render
Can anyone explain this case to me? Here is my code: https://codesandbox.io/s/react-playground-ddqzc?file=/index.js
import React, { useState, useEffect } from 'react';
const useAutoIncrement = () => {
const [num, setNum] = useState(0)
useEffect(() => {
console.log("useAutoIncrement useEffect")
const interval = setInterval(() => {
console.log("useAutoIncrement useEffect interval")
setNum((currentNum) => {
return 0 // return fixed number
})
}, 5000)
return () => {
console.log("useAutoIncrement useEffect return")
clearInterval(interval)
}
});
console.log("render useAutoIncrement")
return 0
}
const CustomHook = () => {
const initialCount = {value: 5};
const [count, setCount] = useState(initialCount);
const num = useAutoIncrement()
const handleIncrement = () => {
setCount((currentCount) => {
return Object.assign({}, currentCount, {value: 2})
});
console.log("handleIncrement")
}
useEffect(() => {
console.log("CustomHook useEffect")
return () => {
console.log("CustomHook useEffect return")
}
})
console.log("CustomHook render")
return (
<div>
<h1>{count.value}</h1>
<button type="button" onClick={handleIncrement}>
Increment
</button>
<p>Auto Increase Number: {num}</p>
</div>
);
};
export default CustomHook;
Upvotes: 0
Views: 1441
Reputation: 7658
When you clicked the button and fired the state change, your component was updated and re-rendered - you can see this from your logging above.
render useAutoIncrement
CustomHook render
useAutoIncrement useEffect return
useAutoIncrement
's useEffect will be ranCustomHook useEffect return
useAutoIncrement useEffect
CustomHook useEffect
useAutoIncrement useEffect interval
render useAutoIncrement
CustomHook render
num
is updated too, even tho it's the same numberHope this helps some
Upvotes: 1