1

問題: をthunk導入する前にミドルウェアを使用すると、サンクRedux.combineReducersgetState渡された は正しいキーを持つオブジェクトを正しく返します。Redux.combineReducersuseにリファクタリングした後getState、サンクに渡された は、ネストされたキーを持つオブジェクトを返すようになりました。以下のコードを参照してください。これは (うまくいけば) 私の要点を示しています。thunkこれにより、状態にアクセスするメソッドの正しいキーを常に取得しなければならないという潜在的なメンテナンスの悪夢につながる可能性があります。

質問: 内で正しいコンテキスト キーを設定する簡単な方法はありますthunkか? レデューサーを組み合わせて正しい状態にアクセスするためにキーを挿入する必要があると、コードが脆く感じます。簡単なものがありませんか?

コードの前:

const Redux = require('redux'),
    Thunk = require('redux-thunk');

// this is an action generator that returns a function and is handled by thunk
const doSomethingWithFoo = function() {
    return function(dispatch, getState) {
        // here we're trying to get state.fooValue
        const fooValue = getState().fooValue;
        dispatch({ type: "DO_SOMETHING", fooValue });
    }
};
// this is a simple action generator that returns a plain action object
const doSimpleAction = function(value) {
    // we simply pass the value to the action. 
    // we don't have to worry about the state's context at all.
    // combineReducers() handles setting the context for us.
    return { type: "SIMPLE_ACTION", value };
}

const fooReducer(state, action) {
    // this code doesn't really matter
    ...
}

const applyMiddleware = Redux.applyMiddleware(Thunk)(Redux.createStore);
const fooStore = applyMiddleware(fooReducer);

コードの後 (よりグローバルな appStore の導入):

// need to rewrite my thunk now because getState returns different state shape
const doSomethingWithFoo = function() {
    return function(dispatch, getState) {
        // here we're trying to get state.fooValue, but the shape is different
        const fooValue = getState().foo.fooValue;
        dispatch({ type: "DO_SOMETHING", fooValue });
    }
};


const appReducers = Redux.combineReducers({
    foo: fooReducer,
    bar: barReducer,
});
const appStore = applyMiddleware(appReducers);
4

2 に答える 2

1

あなたは物事を考えすぎています。定義により、store.getState()状態全体を返し、combineReducers()複数のサブレデューサーをまとめて大きなオブジェクトにします。どちらも意図したとおりに機能しています。あなたは独自のアプリケーションを作成しているので、状態の形を実際にどのように編成し、それを処理するかについて責任を負います。このように物事があまりにも「もろい」と感じた場合、物事を構造化する良い方法を見つけるのはあなた次第ですが、それは Redux の問題ではありません。

また、getState()アクションクリエーターで何をすべきかを決定するために使用することは、完全に有効なアプローチです。実際、Redux docsのReducing Boilerplateセクションでは、デモンストレーションとしてそれを行っています。

export function addTodo(text) {
  // This form is allowed by Redux Thunk middleware
  // described below in “Async Action Creators” section.
  return function (dispatch, getState) {
    if (getState().todos.length === 3) {
      // Exit early
      return
    }

    dispatch(addTodoWithoutCheck(text))
  }
}
于 2016-01-08T18:13:31.167 に答える
1

もう少し考えた結果、答えはdoSomethingWithFooアクションジェネレーターをリファクタリングして、パラメーターとして受け入れるようにすることだと思いfooValueます。そうすれば、状態オブジェクトの形状が変化することを心配する必要はありません。

const doSomethingWithFoo(fooValue) {
    return function(dispatch, getState) {
        // now we don't have to worry about the shape of getState()'s result
        dispatch({ type: "DO_SOMETHING", fooValue });
    }
}
于 2016-01-07T23:34:04.337 に答える