问题描述
在 React 组件中,父组件通过 props 把数据传递给子组件,但是当父组件的 state 改变时,子组件不会自动更新,依然显示原来的数据。这是一个常见的问题,如果不处理,会给应用带来很多麻烦。
问题原因
React 采用的是 Virtual DOM,当父组件的 state 改变时,React 会比对 Virtual DOM,找出哪些部分需要重新渲染,然后才会把新的 Virtual DOM 挂载到真实 DOM 上。但是,如果只是传递给子组件的 prop 改变了,React 并不会重新渲染子组件,因为子组件是 PureComponent 或者是 shouldComponentUpdate 方法返回 false。这样会导致子组件的数据不会更新,界面也不会更新。
解决方法
1. 将所有属性都传递给子组件
这个方法比较简单,就是把所有的 props 都传递给子组件。这样,当父组件的 state 改变时,所有的 props 都会改变,从而强制子组件重新渲染。但是,这种方法对于性能来说并不是很友好,因为每次渲染都要重新传递所有的 props。
-- -------------------- ---- ------- ----- ------ ------- --------------- - ------------------ - ------------- ---------- - - ------ ----- -- - -------- - ------ - ------ ------------------------ -- -- - - ----- ----- ------- --------------- - -------- - ------ - ----------------------------- -- - -
2. 使用 key
React 会使用每个组件的 key 来判断是否需要重新渲染。如果组件的 key 发生了改变,React 就会重新渲染组件。因此,我们可以使用一个变量作为 key,当父组件的 state 改变时,改变 key 的值,从而强制子组件重新渲染。
-- -------------------- ---- ------- ----- ------ ------- --------------- - ------------------ - ------------- ---------- - - ------ ------ ---- - -- - ----------- - -- -- - --------------- ------ ------ ---- -------------- - - --- - -------- - ------ - ----- ------ -------------------- ------------------------ -- ------- --------------------------------- -------------- ------ -- - - ----- ----- ------- --------------- - -------- - ------ - ----------------------------- -- - -
3. 使用 shouldComponentUpdate
如果我们不想传递所有的 props 或者不想使用 key,我们可以在子组件中重写 shouldComponentUpdate 方法,判断 props 是否改变,如果改变则返回 true,否则返回 false。这个方法会在父组件的 state 改变时调用,用来判断是否需要重新渲染子组件。
-- -------------------- ---- ------- ----- ----- ------- --------------- - -------------------------------- - ------ --------------- --- ----------------- - -------- - ------ - ----------------------------- -- - -
总结
无论使用哪种方法,我们都需要保证子组件不因为一个简单的 prop 改变而导致不必要的性能损失。使用 key 可以使得 React 在重新渲染组件时更有效率,而重写 shouldComponentUpdate 方法可以让我们更精细地控制子组件的更新,避免不必要的渲染。在实际使用中,我们可以根据具体的情况选择最适合的方法,以避免不必要的性能问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f5762bf6b2d6eab3e2e1a0