繁体   English   中英

当状态相同时,为什么 React 会重新渲染组件?

[英]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' };
  }
});

如果您有一些最喜欢的用于检查深度相等的库(例如lodashramda ),您可以将其缩短为如下所示。 如果您需要检查很多属性,这将特别有用:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM