Редукторы React и бесшовные неизменяемые

Я новичок в редукторе и неизменяемой штуке, так что, может быть, кто-нибудь ответит мне на несколько вопросов. Я использую бесшовные неизменяемые (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 позаботится об этом, и этого достаточно, чтобы сделать const PRODUCTS_INITIAL_STATE = Immutable({ data: [], loading: true });?
  2. Я прав, что подход JSX с использованием трех точек { ...state, loading: action.payload } аналогичен использованию Immutable.merge?
  3. Есть ли более простой способ для действия ADD_PRODUCT добавить элемент в массив, вложенный в объект?

Обновить

Возник еще один вопрос: у меня есть неизменяемый массив, содержащий объекты. Когда я хочу добавить еще один элемент, мне нужно воссоздать массив, используя Immutable(array).concat(newElement). Но что, если я хочу заменить значение только внутри одного из его объектов?

Рассмотрим этот массив:

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

Что делать, если я хочу изменить имя первого элемента с foo на hello?


person 23tux    schedule 23.07.2017    source источник


Ответы (1)


Я также новичок в неизменном. Но это мой неизменно неизменный опыт после прочтения исходного кода моего друга.

  1. Должен ли я определять каждое свойство как неизменяемый объект, как в const PRODUCTS_INITIAL_STATE = Immutable ({data: Immutable ([]), loading: true}); или Immutable позаботится об этом, и достаточно сделать const PRODUCTS_INITIAL_STATE = Immutable ({data: [], loading: true}) ;?

Да, Immutable({ data: [], loading: true }); вполне достаточно. Не нужно вкладывать неизменяемый объект в неизменяемый.

  1. Я прав, что подход JSX с использованием трех точек {... state, loading: action.payload} аналогичен использованию Immutable.merge?

{ ...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 добавить элемент в массив, вложенный в объект?

Кому-то это нравится, да?

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

const newState = state.merge({ data: [...state.data, "new item"] });
  1. Что делать, если я хочу изменить имя первого элемента с foo на hello?

Просто используйте set api

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

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

У вас есть еще вопросы?

person Long Nguyen    schedule 03.06.2019