从React DOCS:
https://reactjs.org/docs/state-and- lifecycle.html
状态更新可能是异步的 React可以将多个setState()调用批处理到单个更新中以提高性能。
状态更新可能是异步的
React可以将多个setState()调用批处理到单个更新中以提高性能。
这是完全合理的。如果您具有类似下面的功能,则在每次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完成,正在重新绘制一定会发生的 immediatelly handleClick做跑步?我的意思是立即立即,就像立即同步一样?
handleClick
从我构建的这段代码来看,这似乎是对的。完成后,React将 同步 应用更新(重新渲染)handleClick。如果我认为不对,请纠正我。
请参见下面的代码段:
props.counter
App
counter
题
当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"/>
一旦handleClick完成,正在重新绘制一定会发生的immediatelly handleClick做跑步?我的意思是立即立即开始,就像立即同步
对于某些事件,包括click,React保证在另一个事件发生之前会重新渲染组件。(对于其他事件,情况并非如此mousemove。)您可以在此处找到哪些事件。当前的术语似乎是DiscreteEvents是保证存在的术语,而UserBlockingEvents是不保证存在的术语。在当前的实现中,很可能意味着它是在事件处理结束时同步完成的¹,但我认为保证并不那么具体。
click
mousemove
DiscreteEvent
UserBlockingEvent
我在Twitter上从Dan Abramov那里学到了这一点(他在活动中使用了较旧的术语)。
¹编辑:而事实上,在他的回答约瑟夫D.点,由丹阿布拉莫夫评论说,这是,现在,也说 :“这是实现细节,并在未来的版本可能会改变” 。