Из React DOCS:
https://reactjs.org/docs/state-and-lifecycle.html
Обновления состояний могут быть асинхронными
React может пакетировать несколько вызовов setState ()в одном обновлении для производительности.
Это имеет смысл.Если у вас есть что-то похожее на функцию ниже, было бы очень неэффективно повторять рендеринг при каждом setState
вызове
const [state1,setState1] = useState(false);
const [state2,setState2] = useState(false);
const [state3,setState3] = useState(false);
function handleClick() {
setState1(true);
setState2(true);
setState3(true);
}
Так что, в ситуации выше, я ожидаю, что React будет пакетировать все 3 setState
звонки в один повторный рендер.И это именно так!
Но я хочу знать следующее:
После того, как handleClick
завершено, гарантируется повторный рендер немедленно handleClick
уже работает?Я имею в виду буквально сразу, как синхронно сразу?
Из этого фрагмента, который я построил, кажется, что это правда.Реагирует синхронно применяет обновления (повторной визуализации) после завершения handleClick
.Поправьте меня, если я ошибаюсь, предполагая, что.
См. Фрагмент ниже:
- Нажмите в 3 раза быстрее, чем вы можете
handleClick
вызоветsetState
и будет записывать текущее значение props.counter
- На
App
есть дорогой цикл, поэтому потребуется много времени для повторного рендеринга - Вы сможетещелчок намного быстрее, чем React может перерисовать все приложение
- Но вы увидите, что
props.counter
отличается каждый раз, без повторов, даже если вы нажимаете несколько раз очень быстро - Это означает, что после обработки вашего второго клика (это займет некоторое время из-за дорогого цикла), React уже заново отрендерил все это, и функция
handleClick
уже была воссоздана с новым значением для props.counter
, котороепришел из обновленного состояния counter
. - Попробуйте нажать 5 раз очень быстро, и вы увидите, что поведение такое же.
ВОПРОС
Когда setState
вызовы выполняются внутри функции обработчика событий, сразуФункция обработчика завершила работу, гарантируется ли, что повторное отображение будет выполнено немедленно (синхронно) после этого завершения обработчика?
function App() {
console.log("App rendering...");
const [counter, setCounter] = React.useState(0);
// AN EXPENSIVE LOOP TO SLOW DOWN THE RENDER OF 'App'
for (let i = 0; i < 100000; ) {
for (let j = 0; j < 10000; j++) {}
i = i + 1;
}
return <Child counter={counter} setCounter={setCounter} />;
}
function Child(props) {
console.log("Child rendering...");
// THIS FUNCTION WILL CALL 'setState'
// AND WILL ALSO LOG THE CURRENT 'props.counter'
function handleClick() {
props.setCounter(prevState => prevState + 1);
console.log(props.counter);
}
return (
<React.Fragment>
<div>Counter: {props.counter}</div>
<button onClick={handleClick}>Click</button>
</React.Fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>