使用 '''for 实现组合化简器.在''''



在 Redux egghead.io 系列的第 16 课中,我尝试实现自己的 combineReducers 函数,然后再看 Dan 是如何做到的。我得到了以下几点。我试图在子减速器(todosvisibilityFilter)上使用for ... in,就像这样传入

const combineReducers  = (reducers) => {
   return (state,action) => {
    let temp = {};
    for (let i in reducers) {
      temp[i] =  reducers[i](state,action)
    }
    return temp;
  }
}

这行不通。当我使用预期库对其进行测试时,我在控制台中收到以下错误。奇怪的是,如果我没记错的话,看起来从调用到todos化简器的状态已经嵌套到visibilityFilter化简器的调用中。这很奇怪,因为我的代码显示它们是返回的对象中明显独立的字段。

未捕获的错误: 预期 { 待办事项: [ { 已完成: 假, id: 1, 文本: '去购物' } ], 可见性过滤器: { 待办事项: [ { 已完成: 假, id: 0, 文本: 'Learn Redux' } ], visibilityFilter: 'SHOW_ALL' } } to 等于 { 待办事项: [ { 已完成: 假, id: 0, 文本: 'Learn Redux' }, { 已完成:假,ID:1,文本:"去购物"} ],可见性过滤器: 'SHOW_ALL' }

我的测试代码是

const testTodoApp = () => {
  const stateBefore = {
    todos: [{id: 0, text:'Learn Redux', completed: false}],
    visibilityFilter: 'SHOW_ALL',
  };
  // action is an object. with a defined type property.
  const action = {
    type: 'ADD_TODO',
    id: 1,
    text: 'Go shopping',
  };
  const stateAfter = {
    todos: [{id: 0, text:'Learn Redux', completed: false},
            {id: 1, text:'Go shopping', completed: false},
            ],
    visibilityFilter: 'SHOW_ALL',
  };
  deepFreeze(stateBefore);
  deepFreeze(action);
  expect(
    todoApp(stateBefore, action)
  ).toEqual(stateAfter);
  console.log("Test passed: todoApp")
}
testTodoApp();

如果我使用内置的组合减速器,此测试将通过。子减速器和调用combineReducers如下:

const todo = (state = {} ,action) => {
  switch (action.type) {
    case 'ADD_TODO':
    return {
      id: action.id, text: action.text, completed: false,
    };
    case 'TOGGLE_TODO':
    if (state.id !== action.id) {
      return state;
    }
    return {
      ...state, completed: !state.completed,
    };
    default:
    return state;
  }
}
const todos = (state=[], action) =>{
  switch (action.type) {
    case 'ADD_TODO':
    console.log('ADD_TODO switch selected')
    return [
      ...state,
      todo(undefined,action),
    ];
    case 'TOGGLE_TODO':
    console.log('TOGGLE_TODO switch selected')
    return state.map( t => todo(t, action))
    default:
    console.log('default switch selected')
    return state;
  }
}
const visibilityFilter = (
  state = 'SHOW_ALL',
  action
) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter;
    default:
      return state;
  }
}

const todoApp = combineReducers({
  todos,
  visibilityFilter,
})

我的问题是:

  1. 我的代码中是什么导致一个化简器嵌套在另一个化简器中?
  2. 我意识到 Dan 改用了reduce,但出于教学原因,我如何使用 for ... in 模式来实现组合化简器?
  3. 之后,您能否评论一下将for ... in用于此类应用程序的适当性,如果这是一个糟糕的模式,是什么让它如此?

我刚刚意识到todos化简器和visibilityFilter化简器必须传递与其键对应的组合状态部分,而不是整个组合状态。所以工作代码应该看起来像这样,我在第 5 行的状态的相应部分添加了一个对象访问器。

const combineReducers  = (reducers) => {
   return (state,action) => {
    let temp = {};
    for (let i in reducers) {
      temp[i] =  reducers[i](state[i],action)
    }
    return temp;
  }
}

最新更新