2016-06-24 3 views
0

Ich habe versucht, dies für ein paar Stunden jetzt herauszufinden ... Wie stelle ich die vollständige um in Notes innerhalb der Task-Objekt wechseln?Set item, um 2 Ebenen tief in Redux Reducer zu vervollständigen

Komme ich rechts davon?

Reducer:

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

Aktionen:

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

Auftraggeber:

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

Antwort

0

Es scheint, wie man so ziemlich einen Weg gefunden haben, damit es funktioniert. Solange jede Notiz mit genau einer Aufgabe verknüpft ist und dieser Code keinen Leistungsengpass erzeugt, bleibe ich wahrscheinlich bei der Lösung, die Sie erarbeitet haben. Wenn Sie möchten, kann ich auf eines dieser möglichen Probleme näher eingehen, aber ich denke, Ihr Ansatz würde für eine einfache Todo-App gut funktionieren.

bearbeiten

Ihren Kommentar gelesen, ich sehe jetzt, dass Sie einen Fehler zu arbeiten, und nicht nur gefragt sind versuchen, ob es ein „besserer Weg“ ist. Tut mir leid, dass ich zu schnell gelesen habe. Um das Problem zu beheben, sollten Sie die Aufgabe in Ihrem elseif Block zurückgeben. Zum Beispiel:

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 
     }) 
    }) 
    }); 
} 
+0

Ich möchte es einfach halten. Nachdem es den Reduzierer für COMPLETE_NOTE durchlaufen hat, wird die Aufgabe selbst undefiniert. Was schlägst du meinen Code vor? –

+0

Whoops, ich habe gerade dein Problem bemerkt. Im Rumpf des elseif-Blocks sollten Sie die Aufgabe mit der Eigenschaft der modifizierten Notizen zurückgeben. Überprüfen Sie die Änderung in meiner Antwort. – Brandon

+0

Danke für die Antwort. Keine Sorge, ich hätte klarer sein können. Wie auch immer, es scheint den Spread-Operator nach der ersten Rückkehr nicht zu mögen. –

0

Sie tun es falsch.

Zuerst, anstelle von einem Array von Aufgaben, schlage ich vor, Sie erstellen ein Objekt, wo die Todos durch ihre IDs zugeordnet sind. Das gleiche für die Notizen. Also Ihr Zustand Objekt würde wie folgt aussehen:

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

Dann ein Reduktionsmittel für jeden Teil des todo erstellen und beachten Sie und verwenden Sie die combineReducers Funktion ein Task-Objekt zu erstellen. Also in Ihrem Code, den Sie so etwas wie dieses haben würde:

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 

Eine der Grundideen von Redux ist, dass man viele Reduzierungen und jeder von ihnen haben kümmert sich um nur einen kleinen Teil des gesamten Staates. Dies trennt Probleme und macht den Code einfacher zu pflegen.

Ich schlage vor, Sie watch Dan Abramov's (the author of Redux) free course Idiomatic Redux, wo er über all diese Sachen spricht.

Verwandte Themen