[英]Why is React rerendering the component when the states are the same?
我的反應組件中有一個object state 設置如下:
const [state, setState] = useState({ keyOne: true, keyTwo: 'someKey' })
當我更改 state 時,組件顯然會重新渲染。 但這就是問題所在。 即使我將 state 更改為當前設置的值,該組件仍在重新渲染。 例如,如果我這樣做,組件仍然會重新渲染:
setState({ keyOne: true, keyTwo: 'someKey' });
我猜這是因為我將新的 object 傳遞給setState
,因此即使 object 中的內容相同,每次它都會被解釋為不同的 state 所以我想我的問題是:
如果新的 object state 與原始 state 具有相同的內容,如何防止組件重新渲染? 有沒有內置的方法可以做到這一點,還是我必須自己事先比較對象?
它正在重新渲染,因為新的 object 與之前的 object 不同。 它內部可能具有所有相同的屬性,但 react 只進行了淺顯的比較。
如果你想跳過渲染,你需要確保 object 參考沒有改變。 例如:
setState(prev => {
if (prev.keyOne === true && prev.keyTwo === 'someKey') {
return prev; // Same object, so render is skipped
} else {
return { keyOne: true, keyTwo: 'someKey' };
}
});
如果您有一些最喜歡的用於檢查深度相等的庫(例如lodash或ramda ),您可以將其縮短為如下所示。 如果您需要檢查很多屬性,這將特別有用:
setState(prev => {
const next = { keyOne: true, keyTwo: 'someKey' };
return R.equals(prev, next) ? prev : next;
});
一種選擇是為 object 的不同屬性使用單獨的狀態。 這樣,只有在新的 state 值之一不同時才會觸發重新渲染。 舉個小例子:
const App = () => { console.log('rendering'); const [val, setVal] = React.useState(true); React.useEffect(() => { setVal(true); }, []); return 'foo'; }; ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div class='react'></div>
如您所見,盡管調用了 state 設置器,但組件不會重新渲染,因為新的 state 與舊的 state 相同。
對於你的代碼,你會有類似的東西
const [keyOne, setKeyOne] = useState(true);
const [keyTwo, setKeyTwo] = useState('someKey');
使用上述方法而不是將 state 放入單個 object 是功能組件的一種非常常見的做法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.