反应减速器&无缝不变

时间:2017-07-23 09:45:37

标签: react-native redux immutability seamless-immutable

我是整个减速器和不可变的东西的新手,所以也许有人可以回答我一些问题。我在react本机应用程序中使用了seamless-immutable(https://github.com/rtfeldman/seamless-immutable)和redux-seammless-immutable(https://github.com/eadmundo/redux-seamless-immutable)。

我对以下代码有一些疑问:

import { combineReducers } from 'redux-seamless-immutable';
import Immutable from 'seamless-immutable';

const PRODUCTS_INITIAL_STATE = Immutable({ data: Immutable([]), loading: true });

const productsReducer = (state = PRODUCTS_INITIAL_STATE, action) => {
  switch (action.type) {
    case "LOADING":
      return { ...state, loading: action.payload };
    case "LOADED":
      return Immutable.merge(state, {data: Immutable(action.payload) });
    case "ADD_PRODUCT":
      return Immutable.merge(state, {data: Immutable(state.data).concat(action.payload) });
    default:
      return state;
  }
};

const INIT_STORE = Immutable({
  products: productsReducer
});
export default combineReducers(INIT_STORE);
  1. 我是否必须将每个属性定义为const PRODUCTS_INITIAL_STATE = Immutable({ data: Immutable([]), loading: true });中的Immutable对象,或者Immutable是否会处理这个问题,并且只需要const PRODUCTS_INITIAL_STATE = Immutable({ data: [], loading: true });
  2. 我是对的,使用三个点{ ...state, loading: action.payload }的JSX方法与使用Immutable.merge相同吗?
  3. ADD_PRODUCT操作是否有更简单的方法,可以将元素添加到嵌套在对象中的数组中?
  4. 更新

    另一个问题:我有一个包含对象的不可变数组。当我想添加另一个元素时,我必须使用Immutable(array).concat(newElement)重新创建数组。但是如果我只想替换其中一个对象的值呢?

    考虑这个数组:

    const array = Immutable([
      { name: "foo" },
      { name: "bar" }
    ]);
    

    如果我想将第一个元素的名称从foo更改为hello,那么不可改变的方法是什么?

1 个答案:

答案 0 :(得分:0)

我还是一成不变的新手。但这是我阅读我的朋友源代码后的无缝不变的经验。

  
      
  1. 我是否必须像const中一样将每个属性都定义为不可变对象   PRODUCTS_INITIAL_STATE =不可变({数据:不可变([]),正在加载:   true});还是Immutable会解决这个问题,而做一个   const PRODUCTS_INITIAL_STATE = Immutable({data:[],loading:true   });?
  2.   

是的,Immutable({ data: [], loading: true });就足够了。无需在不可变内部嵌套不可变对象。

  
      
  1. 我说对了,JSX方法使用三个点{...   loading:action.payload}与使用Immutable.merge相同?
  2.   

{ ...state, loading: action.payload }state.merge({ loading: action.payload })相同,但是Immutable.merge将返回Immutable对象。您可以使用无缝不可变的isImmutable函数来检查对象是否不可变。

const demo = Immutable({ foo: 1, bar: "hello" });

console.log("isImmutable", isImmutable({ ...demo, test: 69 }));   // false
console.log("isImmutable", isImmutable(demo.merge({ test: 1 })));   // true
  
      
  1. 是否有更简单的方法来添加元素ADD_PRODUCT   到嵌套在对象内的数组?
  2.   

喜欢这样,对吧?

const PRODUCTS_INITIAL_STATE = Immutable({ data: ['old item'], loading: true });

const newState = state.merge({ data: [...state.data, "new item"] });
  
      
  1. 如果我想将第一个元素的名称从foo更改为hello,那将是一成不变的方法吗?
  2.   

只需使用set API

const array = Immutable([{ name: "foo" }, { name: "bar" }]);

const mutatedArray = array.set(0, { name: "hello" });

还有其他问题吗?