我正在學習 React,并且難以理解正在發生的代碼流。
這是我的代碼:它是一個功能性的 React 組件
function App() {
const [x, setx] = useState(1);
const [x1, setx1] = useState(1);
const [x2, setx2] = useState(1);
const [x3, setx3] = useState(1);
const [x4, setx4] = useState(1);
const [x5, setx5] = useState(1);
console.log("out3");
const bclick = () => {
setx1(x1 1);
setx2(x2 1);
setx3(x3 1);
setx4(x4 1);
setx5(x5 1);
setx(x 1);
console.log("out1");
bclick2();
};
const bclick2 = () => {
console.log("out2");
};
console.log("out4");
return (
<div className="App">
{console.log("in")}
<button onClick={bclick} />
</div>
);
}
點擊按鈕后console.log()的輸出:out1 out2 out3 out4 in
Q> 點擊按鈕后會執行多個不同的 setState。他們是否會重新評估組件或功能鏈(bclick 和 bclick2)完成執行,然后重新評估 App 組件。根據我的輸出,我意識到首先執行功能鏈。這就是 setState 的作業原理嗎?代碼流是否會首先完成(無論功能數量如何),然后重新評估功能組件?
uj5u.com熱心網友回復:
這與 React 批處理setState呼叫以優化渲染數量有關。通常你不必擔心這一點。
setState電話async是。React 將決定何時以及如何應用多個setState呼叫。
處理程式將始終在 React 重新渲染之前完成運行。這就是為什么您bclick2()在重新渲染之前看到呼叫正在運行的原因。
我覺得 React 總是會setState在一次重新渲染中批量處理多個呼叫。但是您可以看到,如果您將多個setState呼叫包裝在 中setTimeout,React 將重新渲染多次,因為它無法知道這些超時需要多長時間才能完成。例如,您可能正在呼叫 API。
function App() {
console.log('Rendering App...');
const [x, setx] = React.useState(1);
const [x1, setx1] = React.useState(1);
const [x2, setx2] = React.useState(1);
const [x3, setx3] = React.useState(1);
const [x4, setx4] = React.useState(1);
const [x5, setx5] = React.useState(1);
const bclick = () => {
console.clear();
console.log("From bclick (batched: single render)");
setx1(x1 1);
setx2(x2 1);
setx3(x3 1);
setx4(x4 1);
setx5(x5 1);
setx(x 1);
console.log("Calling bclick2");
bclick2();
};
const bclick2 = () => {
console.log("From bclick2");
};
const notBatched = () => {
console.clear();
console.log('From notBatched (multiple renders)');
setTimeout(() => setx1((prevState) => prevState 1),0);
setTimeout(() => setx1((prevState) => prevState 1),0);
setTimeout(() => setx1((prevState) => prevState 1),0);
};
return (
<div className="App">
<button onClick={bclick}>Click (will batch)</button>
<button onClick={notBatched}>Click (will not batch)</button>
</div>
);
}
ReactDOM.render(<App/>,document.getElementById("root"));
<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"/>
例如,如果您從 a 呼叫 API useEffect:
useEffect(() => {
setIsLoading(true); // 1
const data = await fetchAPI();
setData(data); // 2
setIsLoading(false); // 3
},[]);
In this case React wil run #1, and then, when the API call completes, it will run #2 and #3 separately (not batched). Not sure why it chooses to do it separately, because it would be safe to run them together, but I'm sure React has its own reasons for that. Probably the whole block that has been timeout'd because of the API call is flagged to shouldNotBatch somehow. I don't actually know what is the internal logic they use for this.
const fetchAPI = () => {
return new Promise((resolve) => {
setTimeout(() => resolve('DATA'),1500);
});
}
const App = () => {
console.log('Rendering App...');
const [isLoading,setIsLoading] = React.useState(false);
const [data,setData] = React.useState(null);
// I changed the `await` to `then` because SO snippets don't allow `await` in this case
React.useEffect(() => {
console.log('Running useEffect...');
setIsLoading(true); // 1
fetchAPI().then((data) => {
setData(data); // 2
setIsLoading(false); // 3
});;
},[]);
return(
<div>
<div>isLoading:{JSON.stringify(isLoading)}</div>
<div>data:{JSON.stringify(data)}</div>
</div>
);
};
ReactDOM.render(<App/>, document.getElementById("root"));
<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"/>
React v18 (apr-2022)
Apparently React v18 batches call from async handlers as well.

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/456694.html
標籤:javascript 反应 异步 反应钩子 设置状态
上一篇:我怎么能這樣當我點擊一個按鈕時它會解決一個promise,如果我再次點擊它會等到前一個promise被解決
下一篇:如果陳述句不適用于全域變數
