Подтвердить что ты не робот

Как использовать Immutable.js с сокращением?

Redux использует reducers для изменения состояния приложения в ответ на действие.

Ключевым требованием является то, что редуктор не может изменять существующий объект состояния; он должен создать новый объект.

Плохой пример:

import {
    ACTIVATE_LOCATION
} from './actions';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state.activeLocationId = action.id;
            break;
    }

    return state;
};

Хороший пример:

import {
    ACTIVATE_LOCATION
} from './actions';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = Object.assign({}, state, {
                activeLocationId: action.id
            });
            break;
    }

    return state;
};

Это хороший вариант использования Immutable.js.

4b9b3361

Ответ 1

Принимая ваш хороший пример с неизменным

import {
    ACTIVATE_LOCATION
} from './actions';

import { Map } from 'immutable';

const initialState = Map({})

export let ui = (state = initialState, action) => {
  switch (action.type) {
    case ACTIVATE_LOCATION:
      return state.set('activeLocationId', action.id);
    default:
      return state;
  }
};

Ответ 2

Immutable.js следует использовать в каждом редукторе по мере необходимости, например

import {
    ACTIVATE_LOCATION
} from './actions';

import Immutable from 'immutable';

export let ui = (state, action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = Immutable
                .fromJS(state)
                .set('activeLocationId', action.id)
                .toJS();
            break;
    }

    return state;
};

Однако в этом примере много накладных расходов: каждый раз, когда вызывается действие редуктора, он должен преобразовать объект JavaScript в экземпляр Immutable, мутировать полученный объект и преобразовать его обратно в объект JavaScript.

Лучший подход состоит в том, чтобы иметь исходное состояние экземпляр Immutable:

import {
    ACTIVATE_LOCATION
} from './actions';

import Immutable from 'immutable';

let initialState = Immutable.Map([]);

export let ui = (state = initialState, action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = state.set('activeLocationId', action.id);
            break;
    }

    return state;
};

Таким образом, вам нужно только преобразовать исходное состояние в экземпляр Immutable ounce. Затем каждый редуктор будет рассматривать его как экземпляр Immutable и передать его по строке как экземпляр Immutable. Уловка заключается в том, что теперь вам нужно передать все состояние JavaScript перед передачей значений в контекст представления.

Если вы выполняете несколько мутаций состояния в редукторе, вам может потребоваться пакетные мутации с помощью .withMutations.

Чтобы упростить задачу, я разработал библиотеку redux-immutable. Он предоставляет функцию combineReducers, эквивалентную функции с тем же именем в пакете redux, за исключением того, что он ожидает, что начальное состояние и все редукторы будут работать с неизменным. js.

Ответ 3

Если вы просто ищете простой способ сделать обновления без мутации, я поддерживаю библиотеку: https://github.com/substantial/updeep, которая в моем мнение, это хороший способ сделать это с помощью redux.

updeep позволяет работать с регулярными (замороженными) иерархиями объектов, поэтому вы можете выполнять деструктурирование, просматривать объекты в журналах и отладчике и т.д. Он также имеет мощный API, который позволяет выполнять пакетное обновление. Он не будет столь же эффективным, как Immutable.js для больших наборов данных, потому что он клонирует объекты, если это необходимо.

Вот пример (но еще раз проверьте их в README):

import {
    ACTIVATE_LOCATION
} from './actions';
import u from 'updeep';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = u({ activeLocation: action.id }, state);
            break;
    }

    return state;
};

Ответ 4

Принятый ответ не должен быть принятым ответом. Вам нужно инициализировать состояние, используя неизменяемые и, как указано выше, использование redux-immutablejs

const initialState = Immutable.fromJS({}) // or Immutable.Map({})

const store = _createStore(reducers, initialState, compose(
    applyMiddleware(...middleware),
    window.devToolsExtension ? window.devToolsExtension() : f => f
));

Чем использовать combReducers из redux-immutablejs

Дополнительный совет: Использование response-router-redux работает очень хорошо, поэтому, если вы хотите добавить это, замените редуктор с помощью response-router-redux следующим образом:

import Immutable from 'immutable';
import {
    UPDATE_LOCATION
} from 'react-router-redux';

let initialState;

initialState = Immutable.fromJS({
    location: undefined
});

export default (state = initialState, action) => {
    if (action.type === UPDATE_LOCATION) {
        return state.merge({
            location: action.payload
        });
    }

    return state;
};

Просто импортируйте это в свой корневой редуктор

Это также указано в документации по сокращению-immutablejs

Ответ 5

Взгляните на https://github.com/indexiatech/redux-immutablejs

Это в значительной степени combineReducer и необязательный createReducer, который соответствует стандартам Redux.