IMHO The suggestion from React Hooks FAQ #getDerivedStateFromProps
leads to one first rendering with a value of row
that doesn't correspond to the value of isScrollingDown
. As the call to setIsScrollingDown
only schedules a new rendering and doesn't affect the current rendering, the latter will be executed with the new value of row
and the old value isScrollingDown
.
This behaviour is not equivalent to the static getderivedstatefromprops
method of the component class that allows coherence between row
and isScrollingDown
.
Should not the example be updated with something like the following code in order to guarantee a coherent rendering ? Or did I miss something ?
Thank you !
function ScrollView({row}) {
let [isScrollingDown, setIsScrollingDown] = useState(false);
let [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row changed since last render. Update isScrollingDown.
isScrollingDown = prevRow !== null && row > prevRow
setIsScrollingDown(isScrollingDown);
setPrevRow(row);
}
return `Scrolling down: ${isScrollingDown}`;
}
Here's the important part from the documentation that makes your change unnecessary:
The render where they are out of sync will never be committed to the browser. In fact, if it was returning a child component from the render, the rendering of the children would not execute until after the state has been updated (the children returned from the render that updated the state would be ignored).
Below is an example with console logs added to show this. Notice that when you increment the row, ScrollView renders twice but ScrollingDown only renders once receiving only the last version of ScrollView's state.