reactjs - React、Redux 和不可变

标签 reactjs redux immutable.js

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

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 的优势?

最佳答案

有一个great video关于不可变数据的好处和实现,来自 Lee 在 React Conf 2015 上的演讲。就思考不可变数据和 React 而言,我认为这是必要的查看。

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

简洁代码

你的状态变得越复杂,使用文字和扩展运算符来管理它就越困难。想象一下,您不是平坦的,而是有几层嵌套状态:

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 修改对象时,它会利用它是通过 HashMap 向量实现的事实,尝试共享旧对象和修改后的版本之间的大部分结构。

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

安全

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

使用可变状态,可以将对象引用传递给其他代码,这可能会改变它。改变对象不是“错误”,因此您不会被告知它已更改,也不会出现堆栈跟踪,这意味着很难确定突变来自何处。

无论你的不可变对象(immutable对象)走到哪里,它们都是安全的。

性能

您可以使用不可变数据结构来做出有关是否更新组件的更高级决策。

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

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

虽然这些类型的深度比较可能看起来很昂贵,但它们可以防止您在对象未更改时需要比较或触摸 DOM。

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

关于reactjs - React、Redux 和不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36098580/

相关文章:

javascript - ReactJS:执行函数后重新加载组件?

javascript - 滚动到各自溢出的 div 中的几个元素

react-native - React Native Navigation 和 Redux Persist

javascript - 当从 cookie 异步加载身份验证 token 时,React React-router-dom 私有(private)路由不起作用

javascript - 如何创建一个 redux-observable 史诗,它在做任何事情之前等待 2 个 Action

javascript - 传播运算符与 immutable.js

javascript - 在一行中写一个嵌套的过滤器

html - 如何使用 Typescript 在 React 中定义 <video> 引用的类型?

javascript - 如何使用 Immutable.js 提供 Flux 存储之间的依赖关系?

javascript - react 应用程序错误 'Uncaught ReferenceError: React is not defined'