1

问题:在引入 之前使用thunk中间件时Redux.combineReducersgetState传递给 thunk 的正确返回具有正确键的对象。在重构为 use 之后Redux.combineReducersgetState传递给 thunk 现在返回一个带有嵌套键的对象。请参阅下面的代码(希望)说明我的观点。这可能导致潜在的维护噩梦,即必须不断为任何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

在考虑了更多之后,我认为答案是重构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 回答
1

你多虑了。根据定义,store.getState()返回整个状态,并将combineReducers()多个 sub-reducer 拉到一个更大的对象中。两者都按预期工作。您正在编写自己的应用程序,因此您要负责实际组织状态形状和处理它的方式。如果您觉得这种方式太“脆弱”,您可以自行寻找一种构建事物的好方法,但这不是 Redux 的问题。

此外,getState()在动作创建者中使用来确定要做什么是一种完全有效的方法。事实上,Redux 文档的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 回答