51

Reduxフレームワークはレデューサーを使用して、アクションに応じてアプリの状態を変更します。

重要な要件は、レデューサーが既存の状態オブジェクトを変更できないことです。新しいオブジェクトを生成する必要があります。

悪い例:

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の適切な使用例です。

4

5 に答える 5

48

Immutableであなたの良い例を取る

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;
  }
};
于 2015-08-09T00:25:45.233 に答える
25

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;
};

ただし、この例には多くのオーバーヘッドがあります。reducer アクションが呼び出されるたびに、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このように、初期状態をオンスのインスタンスに変換するだけで済みます。次に、各レデューサーはそれを のインスタンスとして扱い、 のインスタンスImmutableとして行に渡しますImmutable。問題は、値をビュー コンテキストに渡す前に、状態全体を JavaScript にキャストする必要があることです。

レデューサーで複数の状態変更を実行している場合は、 を使用して変更をバッチ処理.withMutationsすることを検討してください。

物事を簡単にするために、redux-immutableライブラリを開発しました。初期状態とすべてのレデューサーがImmutable.jsオブジェクトcombineReducersで動作することを期待することを除いて、redux パッケージの同名の関数と同等の関数を提供します。

于 2015-08-08T11:44:25.963 に答える
8

突然変異なしで更新を行う簡単な方法を探しているだけなら、私はライブラリを維持しています: 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;
};
于 2015-08-08T17:25:02.950 に答える
5

受け入れられた回答は、受け入れられた回答であってはなりません。immutable を使用して状態を初期化し、(前述のように) redux-immutablejs を使用する必要があります

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

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

redux-immutablejs の CombineReducers を使用するよりも

追加のヒント: react-router-redux を使用すると非常にうまく機能するため、これを追加する場合は、react-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;
};

これをルートレデューサーにインポートするだけです

これは redux-immutablejs のドキュメントにも記載されています

于 2016-02-11T01:39:12.977 に答える
2

https://github.com/indexiatech/redux-immutablejsをご覧ください

Redux標準に準拠するのはほとんどcombineReducerオプションです。createReducer

于 2015-09-04T15:38:42.333 に答える