I expect my console.log to show the current value of prevValueRef
each one second. I checked and I saw that prevValueRef
is increasing each second but it doesn’t show it in the console each second while I console it after setting the new value to my ref. It just shows it in first console.log:
const PreviousValueComponent = ({ value }) => {
const prevValueRef = useRef();
const changeRef = useRef(value); //value is a constant number like 4 for example.
useEffect(() => {
prevValueRef.current = changeRef.current;
console.log(`prevValueRef is: ${prevValueRef.current}`)
}, [changeRef.current]);
useEffect(() => {
const interval = setInterval(() => {
changeRef.current++;
}, 1000)
}, [])
return (
<div>
<p>Current Value: {value}</p>
<p>Previous Value: {prevValueRef.current}</p>
</div>
);
};
I expected this in the console:
prevValueRef is:4
prevValueRef is:5
prevValueRef is:6
.
.
.
But it just shows the first one and when I force my component to a rerender after a while, it shows the updated value that is increased:
prevValueRef is:4
prevValueRef is:682
Edit: I expected my first useEffect to run after any change to it’s dependecy(here for ever) without any re-rendering. Was I doing the wrong way?
2
Answers
The issue at hand is that useRef is just a plain javascript object. When you modify the ref.current React has no way of knowing that the value has changed and therefore does not re-render(https://react.dev/reference/react/useRef). If you want react to re-render on update of value you’d be better off using the useState-hook along the lines of this:
You’d then alter these values by calling their respective setter, e.g.
EDIT::
Adding solution as discussed in comments. Where one of the useEffect-calls are replaced by a function which the setInterval-function calls: