Вот важная часть документации, которая делает ваши изменения ненужными:
React повторно запустит компонент с обновленным состоянием сразу после
выход из первого рендера, чтобы он не был дорогим.
Визуализация, где они не синхронизированы, никогда не будет передана в браузер. Фактически, если бы он возвращал дочерний компонент из рендеринга, рендеринг дочерних элементов не выполнялся до тех пор, пока состояние не будет обновлено (дочерние элементы, возвращенные из рендеринга, который обновил состояние, будут игнорироваться).
Ниже приведен пример с консольными журналами, добавленными, чтобы показать это. Обратите внимание, что при увеличении строки ScrollView визуализируется дважды, а ScrollingDown - только один раз, получая только последнюю версию состояния ScrollView.
import React, { useState } from "react";
import ReactDOM from "react-dom";
function ScrollingDown({ isScrollingDown, prevRow, row }) {
console.log("ScrollingDown", isScrollingDown, prevRow, row);
return (
<div>
{`Scrolling down: ${isScrollingDown}`}
<br />
{`prevRow: ${prevRow}`}
<br />
{`row: ${row}`}
</div>
);
}
function ScrollView({ row }) {
let [isScrollingDown, setIsScrollingDown] = useState(false);
let [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row changed since last render. Update isScrollingDown.
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(row);
}
console.log("ScrollView", isScrollingDown, prevRow, row);
return (
<ScrollingDown
isScrollingDown={isScrollingDown}
prevRow={prevRow}
row={row}
/>
);
}
function App() {
const [row, setRow] = useState(1);
return (
<div className="App">
<ScrollView row={row} />
<button onClick={() => setRow(prev => prev + 1)}>Increment Row</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);