将项目设置为在Redux Reducer中完成2级深度

时间:2016-06-24 23:32:34

标签: reactjs redux reducers

现在试图解决这个问题几个小时了... 如何在Task对象中的Notes中设置完成切换?

我接近这个权利吗?

减速机:

let taskReducer = function(tasks = [], action) {
    case 'COMPLETE_NOTE':
      return tasks.map((task) => {
          if(action.taskId !== task.id) {
            return task;
          } else if(action.taskId === task.id) {
            const { notes } = task;
            notes.map((note) => {
              return note.id === action.noteId ?
                Object.assign({}, note, {note: {completed: !note.completed}}): note
            })
          }
        })
default:
      return tasks;
  }
}

操作:

let actions = {
  completeNote: (taskId, noteId) => {
    return {
      type: 'COMPLETE_NOTE',
      taskId: taskId,
      noteId: noteId,
    }
  }
}

客户端:

let initialState = {
  tasks: [{
    id: 1,
    title: 'do this',
    completed: false,
    notes: [{
      id: 0,
      title: 'note1',
      completed: false
    }]
  }]
}

2 个答案:

答案 0 :(得分:0)

您似乎已经找到了一种方法让它发挥作用。只要每个笔记只与一个任务相关联,并且此代码不会产生性能瓶颈,我可能只是坚持使用您已经完成的解决方案。如果您愿意,我可以详细说明这些潜在问题,但我认为您的方法适用于简单的待办事项应用程序。

修改

阅读完您的评论后,我现在看到您正在尝试解决一个错误而不仅仅是询问是否有更好的方法"。很抱歉阅读速度太快。无论如何,要解决问题,您需要在elseif块中返回任务。例如:

else if(action.taskId === task.id) {
  const { notes } = task;
  return {
    ...task,
    notes: notes.map((note) => {
      return note.id !== action.noteId ? note : {
        ...note,
        completed: !note.completed
      };
    })
  };
}

// Without using spread operator

else if(action.taskId === task.id) {
  const { notes } = task;
  return Object.assign({}, task, {
    notes: notes.map((note) => {
      return note.id !== action.noteId ? note : Object.assign({}, note, {
        completed: !note.completed
      })
    })
  });
}

答案 1 :(得分:0)

你做错了。

首先,我建议您创建一个对象,其中todos由其id映射,而不是一系列任务。笔记也一样。所以你的状态对象看起来像:

tasks: {
    "uniqueid1": {
        title: "some task",
        completed: false,
        notes: {
            "noteid1": {
                title: "some note",
                completed: false
            }
        }
    },
    "uniqueid2": {
        ...
    },
    ...
}

然后为todo的每个部分创建一个reducer并注意并使用combineReducers函数创建一个任务对象。所以在你的代码中你会有这样的东西:

const task = combineReducers({
    title: taskTitle,  // taskTitle is a reducer
    completed: taskCompleted,  //taskCompleted is a reducer
    notes
});

// example implementation of the notes reducer:
const notes = (state = {}, action) => {
    switch(action.type) {
        case 'CHANGE_NOTE_TITLE':
        case 'COMPLETE_NOTE':
            return {
                ...state,
                [action.noteId]: note(state[action.noteId], action)
            };
        default:
            return state;
    }
}

const note = (state, action) => {
    switch(action.type) {
        case 'COMPLETE_NOTE':
            return {
                ...state,
                completed: true
            };
        case 'CHANGE_NOTE_TITLE':
            return {
                ...state,
                title: action.newTitle
            };
        default:
            return state;
    }
}
// note that you could split *note* into *title* and *completed* reducers
// and use the combineReducers function again

Redux的一个基本思想是你有许多减速器,每个减速器只能处理整个状态的一小部分。这很好地区分了问题并使代码更易于维护。

我建议你watch Dan Abramov's (the author of Redux) free course Idiomatic Redux谈论所有这些事情。