React,Redux和Immutable

时间:2016-03-19 06:19:51

标签: reactjs redux immutable.js

Immutable与React(以及可选的Redux)一起使用有什么好处?在Redux中,我可以简单地在我的Redurs中使用rest来返回一个新的状态:

const initialState = {
  activeTrackId: '',
  state: 'stopped',
};

export default function (state = initialState, action) {
  switch (action.type) {
    case actions.PROCESS_TRACK_ACTION:
      return {
        ...state,
        activeTrackId: action.state !== 'stopped' ? action.track._id : '',
        state: action.state,
      };
      // ...

我发现它有用的唯一情况是:

shouldComponentUpdate(nextProps) {
  const oldProps = Immutable.fromJS(this.props);
  const newProps = Immutable.fromJS(nextProps);

  return !Immutable.is(oldProps, newProps);
}

据我所知,这甚至可能会误用它。

也许有人可以告诉我在React和Redux的上下文中使用Immutable的优势?

2 个答案:

答案 0 :(得分:5)

关于不可变数据的好处和实现有一个great video,来自Lee在React Conf 2015上的演讲。至于考虑不可变数据和React,我认为这是必不可少的观看。

除此之外,以下是我对此事的一些看法。

Terser Code

你的国家越复杂,用文字和传播运营商管理它就越难。想象一下,你没有平坦,而是有几个嵌套状态:

const initialState = {
  core: {
    tracker: {
      activeTrackId: '',
      state: 'stopped'
    }
  }
};

虽然仍然可以使用点差运算符,但它开始变得单调乏味。

 return {
   ...state,
   core: {
     ...state.core,
     tracker: {
       ...state.core.tracker,
       activeTrackId: action.state !== 'stopped' ? action.track._id : '',
       state: action.state
     }
   }
 };

现在看一下使用Immutable.js的等价物。

import { Map } from 'immutable';

const initialState = Map({
  core: Map({
    tracker: Map({
      activeTrackId: '',
      state: 'stopped'
    })
  })
});

然后我们可以使用持久性API对结构进行深度更改。

return state
  .setIn(
    ['core', 'tracker', 'activeTrackId'],
    action.state !== 'stopped' ? action.track._id : ''
  )
  .setIn(
    ['core', 'tracker', 'state'],
    action.state
  );

值得一提的是,根据您所在州的形状,拆分和嵌套您的减速器可能更有意义。

结构共享

使用ImmutableJS对对象进行修改时,它会利用哈希映射向量实现的事实尝试共享旧对象和修改版本之间的大部分结构。

当您使用spread运算符创建新文字时,您将被迫复制比生成新对象所需的数据更多的数据。

安全

通过保证对象不会发生变异,您可以消除大量的错误。

使用可变状态,可以将对象引用传递给其他代码,这可能会使其变异。变异对象不是“错误”,所以你不会被告知它已被改变,也不会有堆栈跟踪,这意味着很难找出突变的来源。

无论你的不可变对象去哪里,它们都是安全的。

性能

您可以使用不可变数据结构来决定是否更新组件。

shouldComponentUpdate(nextProps) {
  const oldProps = Immutable.fromJS(this.props);
  const newProps = Immutable.fromJS(nextProps);

  return !Immutable.is(oldProps, newProps);
}

虽然这些深度比较可能看起来很昂贵,但是当对象没有改变时,它们会阻止你需要差异化或触摸DOM。

如果你的道具本身是不可变对象,这将更有效,因为fromJS不必重新创建嵌套级别。

答案 1 :(得分:1)

如果你小心,不要改变传递的属性,你不必使用Immutable.js。

由于props是引用,因此对它的任何更改都会影响整个应用程序。

Immutable.js保证它们不能被修改,但如果你没有进行变异,它会对大型应用程序产生性能影响,但好处是,它可以防止任何意外的应用程序状态污染。

您可以查看these videos以获得更深入的解释。