数组和对象会导致Redux和Immutable.js不必要的重新渲染

时间:2019-01-17 23:01:13

标签: javascript reactjs redux react-redux immutable.js

在我的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]);
    }
  });
}

记录的fromto数组包含所有完全相同的数据。

如何防止这些不必要的重新渲染?

我唯一想到的是,在列表组件的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;
  }
}

1 个答案:

答案 0 :(得分:0)

shouldComponentUpdate方法是我处理/看到其他人处理的方式。

请注意,您无需手动遍历集合并比较ID,因为Immutable包含用于比较集合的is method

  

具有与Object.is类似的语义的值相等检查   不可变集合作为值,如果第二个集合相等   包括等效值。

很明显,这假设传递给您组件的状态是不可变对象,据我了解,这是一种最佳实践(请参见use immutable everywhere except your dumb components)。