Reputation: 713
Let's say I have this:
function Example(props) {
const { prop1, prop2 } = props;
const latestProp1 = useRef(prop1);
useEffect(() => {
latestProp1.current = prop1;
}, [prop1]);
useEffect(() => {
console.log(latestProp1.current);
}, [prop2]);
return null;
}
If both prop1
and prop2
change in the same re-render, is it guaranteed that the console would log the new prop1
value?
And if I swap the useEffect hooks' position -
useEffect(() => {
console.log(latestProp1.current);
}, [prop2]);
useEffect(() => {
latestProp1.current = prop1;
}, [prop1]);
would it be guaranteed that the console would log the old prop1
value (from before the render)?
Upvotes: 10
Views: 5270
Reputation: 53944
Yes, if you follow the Rules of Hooks, the call order ensured (hooks are called via array index, check how hooks implemented).
By following this rule, you ensure that Hooks are called in the same order each time a component renders.
Therefore, by simulating a batched set state (both prop1
and prop2
change in the same re-render) you can notice that first
will always be logged before second
:
function Example(props) {
const { prop1, prop2 } = props;
React.useEffect(() => {
console.log("first");
}, [prop1]);
React.useEffect(() => {
console.log("second");
}, [prop2]);
return <>Example</>;
}
function Component() {
const [counter, setCounter] = React.useState(0);
const [counter2, setCounter2] = React.useState(0);
const together = () => {
setCounter2((p) => p + 1);
setCounter((p) => p + 1);
};
return (
<>
<Example prop1={counter} prop2={counter2} />
<button onClick={together}>together</button>
</>
);
}
Upvotes: 9