在我的React项目中,我的Redux状态形状如下:
{
items: [{ ... }, { ... }, { ... }, ...]
form: {
searchField: '',
filter1: '',
filter2: '',
}
}
在一页上有一个表单组件和项目列表组件。我使用的是Immutable.js,因此每当表单字段更新时,都会创建一个全新的items
数组。因为数组引用现在不同,所以即使数组中的数据相同,这也会导致项目列表重新呈现。
在列表组件中,我正在使用componentDidUpdate
来控制日志状态更改,以确认更新后的数组正在触发重新渲染:
componentDidUpdate(prevProps) {
Object.keys(prevProps).forEach((key) => {
if (prevProps[key] !== this.props[key]) {
console.log('changed prop:', key, 'from', this.props[key], 'to', prevProps[key]);
}
});
}
记录的from
和to
数组包含所有完全相同的数据。
如何防止这些不必要的重新渲染?
我唯一想到的是,在列表组件的shouldComponentUpdate
内,遍历数组,并将项目ID与nextProps
进行比较。但是,这似乎效率很低。
这是我的减速器
import Immutable from 'immutable';
import { types } from '../actions';
const initialState = {
items: []
form: {
searchField: '',
filter1: '',
filter2: '',
}
}
export default function reducer(_state = initialState, action) {
const state = Immutable.fromJS(_state);
switch (action.type) {
case types.HANDLE_FORM_CHANGE:
return state.setIn(['form', action.field], action.value).toJS();
default:
return _state;
}
}
答案 0 :(得分:0)
shouldComponentUpdate
方法是我处理/看到其他人处理的方式。
请注意,您无需手动遍历集合并比较ID,因为Immutable包含用于比较集合的is method:
具有与Object.is类似的语义的值相等检查 不可变集合作为值,如果第二个集合相等 包括等效值。
很明显,这假设传递给您组件的状态是不可变对象,据我了解,这是一种最佳实践(请参见use immutable everywhere except your dumb components)。