2016-06-06 3 views
3

Ich bin ziemlich neu und versuche, ein einfaches Lesezeichen Anwendung mit reagieren & redux.Erhalte eine ID zurück von einem Reducer in redux

Ich kann meinen Kopf nicht drehen, um dieses Problem:

Ein Benutzer kann ein Lesezeichen erstellen und fügen Sie es mehrere Ordner. So versende ich eine addMark(bookmark) Aktion, und danach addMark(folder) oder editFolder(folder), wenn der Ordner bereits existiert. Wie Sie sehen können, werden Lesezeichen und Ordner über die gleiche Aktion hinzugefügt, da sie in meinem Statusbaum beide nur Markierungen sind - unterschieden durch ihre Typeigenschaft.

Mein Problem: Wie kann ich die Ordner-Objekte, die das neue Lesezeichen ist, zu den Ordnern Liste der Lesezeichen hinzufügen? Wie kann ich die ID des neu erstellten Bookmarks zwischen den beiden Versendungen abrufen?

Lösungen ich nicht befriedigend:

  1. Ich weiß, wie die Lesezeichen-ID im Minderer erzeugt wird (via Math.max über die bestehende Bookmark-IDs), so kann ich die neue Lesezeichen-ID zwischen dem reproduzieren 2 Sendungen. Das klingt wie ein schlechter Hack.
  2. Bookmarks und Ordner werden im selben State-Zweig (gleicher Reducer) gespeichert, da sie beide nur "Marks" sind, könnte ich eine State-Eigenschaft haben, die auf das zuletzt hinzugefügte Lesezeichen verweist, aber das klingt auch nach einem schlechten Hack .

Ein wenig Quellcode, zu verstehen, was ich habe:

// mapping between dispatcher and props to my react view 
const mapDispatchToProps = (dispatch) => ({ 
    saveMark: (mark) => { 
    if (mark.id) { 
     dispatch(editMark(mark)); 
    } else { 
     dispatch(addMark(mark)); 
    } 
    }, 
}); 
export default connect(mapStateToProps, mapDispatchToProps)(AddMark); 

und innen AddMark, die die Container-Komponente ist:

// save the bookmark first 
this.props.saveMark({ 
     type: 'bookmark', 
     title: this.state.title, 
     url: this.state.url, 
     icon: this.props.icon, 
     style: this.state.style, 
}); 
// now I need the bookmark ID 
folders.forEach(folder => { 
    folder.children.push(bookmarkID) // <-- !!! 
}); 
folders.forEach(folder => this.props.saveMark(folder)); 

ich ein befriedigendes nicht finden können, Lösung dafür.

+0

Warum nicht einfach lassen Sie Ihre 'addMark' Funktion Minderer in zwei Variablen zu übernehmen; Ordner * und Lesezeichen *. – gravityplanx

Antwort

2

Ich denke, dass Sie nur eine Aktion hier versenden sollten: , die sowohl Lesezeichen-Objekt und Ordner akzeptiert.

Ihr Code, der das Hinzufügen eines Lesezeichenobjekts in den Ordner übernimmt, sollte Teil des Reducers sein.

Siehe auch Todos example im Redux-Projekt. Es wurde eine ID in der Aktionserstellung bereitgestellt, um es in der Komponente lesen zu können. Sie können auch aktuellen Zustand zu berechnen neuesten id verwenden:

function addBookmark(bookmark, folder) { 
    return (dispatch, getState) => { 
     const newBookmark = Object.assign({ 
     id: Math.max(0, ...getState().bookmarks.map(b => b.id)) + 1, 
     }, bookmark); 
     dispatch({ 
     type: 'ADD_BOOKMARK', 
     bookmark: newBookmark, 
     folder: folder 
     }); 
    } 
} 

Beachten Sie, dass zB redux-thunk Middleware erfordert diese Aktionen zu versenden.

Dann können Sie den Zugriff auf Lesezeichen mit id bekommen in die Ordner

function folderReducer(state = [], action) { 
    if(action.type === 'ADD_BOOKMARK') { 
    return state.map(folder => { 
     if(folder === action.folder) { 
     return Object.assign({}, folder, {children: [...folder.children, action.bookmark.id]} 
     } 
     return folder; 
    }) 
    } 
    //another reducer code 
    return state; 
} 
+0

Sorry für die lange Verzögerung, aber das ist, was ich gesucht habe! Mir war der zweite Parameter (getState) der inneren Funktion nicht bekannt. –

0

Reduzierungen manipulieren nur die Instanz Ihres Geschäfts. Sie können den aktuellen Snapshot Ihres Staates mit getState()

Verwandte Themen