[英]How to Slow Down React State Update Intentionally - Batch Updates
有時我可能想卸載並重新安裝一個組件,其中包含新數據。 這可能看起來像:
setAllPosts(undefined);
setAllPosts(newArrayOfPosts);
因為 React 批處理狀態變化,取決於 newArrayOfPosts 來自哪里,狀態不會改變。 我已經能夠破解一個 setTimeout() 為 1 秒的解決方案,然后填寫 setAllPosts(),但這感覺太不對勁了。
有沒有一種最佳實踐方法來告訴 React 放慢速度? 或者也許不批量更新這個特定的狀態變化?
PS 我知道有更好的方法可以做到這一點,但我在第三方環境中工作,並且非常受限於我可以訪問的內容。
一旦 react 18 可用(它目前是一個候選版本),就會有一個函數可以強制更新不被批處理: flushSync
import { flushSync } from 'react-dom';
flushSync(() => {
setAllPosts(undefined);
});
flushSync(() => {
setAllPosts(newArrayOfPosts);
});
在那之前,您可能需要執行 setTimeout 方法(盡管它不需要是一整秒)。
PS 我知道有更好的方法可以做到這一點,但我在第三方環境中工作,並且非常受限於我可以訪問的內容。
是的,如果你能做點別的事情可能會更好。 大多數情況下,如果您想故意卸載/重新安裝組件,最好使用您希望重新安裝時更改的key
來實現。
const [key, setKey] = useState(0);
const [allPosts, setAllPosts] = useState([]);
// ...
setKey(prev => prev + 1);
setAllPosts(newArrayOfPosts);
// ...
return (
<SomeComponent key={key} posts={allPosts} />
)
這就是你可以做到的 -
import { flushSync } from 'react-dom';
const handleClick = () => {
flushSync(() => {
setAllPosts(undefined);
// react will create a re-render here
});
flushSync(() => {
setAllPosts(newArrayOfPosts);
// react will create a re-render here
});
};
這用於取消批處理反應狀態。 這只是一種方法。 另一種方法可能是使用setTimeout
。 請注意,在第 18 版的 react 中,setTimeouts 中的狀態更新也被批處理——這被稱為自動批處理,但我們仍然可以通過使用不同的 setTimeouts 來實現這一點——
const handleClick = () => {
setTimeout(() => {
setAllPosts(undefined);
// react will create a re-render here
}, 10);
setTimeout(() => {
setAllPosts(newArrayOfPosts);
// react will create a re-render here
},20);
};
只要確保保持時間差以排除 React 完成的批處理。
有時我可能想卸載並重新安裝一個組件,其中包含新數據。
聽起來這個用例調用了一個useEffect()
,它具有基於您關心的東西的依賴關系,例如向該組件提供的另一塊狀態或道具。
useEffect(() => {
setAllPosts(newArrayOfPosts);
}, [shouldUpdate]);
我什至見過人們觸發useEffect()
的例子,它依賴於一個稱為count
或renderCount
的狀態。 不確定這是否一定是最佳實踐,但這是處理事情的一種方式。
const [count, setCount] = useState(0);
const [allPosts, setAllPosts] = useState([]);
useEffect(() => {
setAllPosts(props.values);
}, [count]);
const handleChange = () => {
setCount(prevCount => prevCount + 1); // This will trigger your useEffect when handleChange() in invoked
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.