2017-01-04 9 views
0

Ich habe einen Speicher, der actions enthält, diese Aktionen sollen durch jedes Mal durchlaufen werden, wenn ein neuer hinzugefügt wird.React componentWillReceiveProps wird Requisiten erhalten, die nicht ausgelöst werden, wenn redux state updates

Ich habe eine Komponente MessageListView, die in einem übergeordneten namens MessageView befindet. Wenn eine neue Aktion zu meinem socketActions.queue Array hinzugefügt wird, soll die componentWillRecieveProps auslösen, aber es tut es nicht. Hier

ist, was mein Minderer wie folgt aussieht:

/* Reducer */ 
const initialState = { 
    queue: [{ 
    type: 'alert', 
    action: 'alert', 
    completed: false, // Set to true or just delete this object when the action has been completed 
    data: { 
     message: "the data object dynamically changes based on the type" 
    } 
    }] 
}; 

export default (state = initialState, action) => { 
    switch (action.type) { 
    case ADD_ACTION: 
    let queue = state.queue 
    // action.data['completed'] = false 
    queue.push(action.data) 
    console.log("Just updated queue", action.data) 

    return { 
     ...state, 
     queue: queue, 
     latestAction: new Date() 
    } 

Meine Komponente ist mit dem Speicher wie folgt angeschlossen:

function mapStateToProps(state){ 
    console.log(state, "State inside messagelistview.js") 
    return { 
    actionsQueue: state.socketActions.queue, 
    latestAction: state.socketActions.latestAction 
    } 
}; 

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ completeAction }, dispatch); 
}; 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(MessageListView); 

Also, wenn ich eine neue ADD_ACTION Aktion versenden, mein Zustand Updates & redux-loggerdruckt den neuen und alten Staat, der mir sagt, dass sie die gleichen sind ?!. Ich weiß nicht, warum es das tun würde, nachdem ich das LatestAction Wert & Queue-Array geändert habe. Deshalb funktioniert das componentWillRecieveProps nicht, aber ich kann nicht herausfinden, warum der Zustand derselbe ist ?!

+0

Wenn Sie Immutable.js verwenden, Sie neigen dazu, mehr in diese Probleme nicht ausgeführt werden. Meiner Ansicht nach ist das Ändern der Objekte von immutable.js sauberer als das Verwenden von Dekonstruktionen und Literalen. – stinodes

Antwort

2

Nicht 100% sicher, wenn das irgendetwas lösen würde, aber ich denke, dass Sie nicht richtig über state.queue in die komplett neue variable Queue kopieren.

Ich würde vorschlagen, wie etwas zu tun:

let queue = state.queue.slice()

... und wenn sich etwas ändert sehen? Ihre queue Variable ist immer noch die gleiche wie die state.queue

+1

Super !! tbh, ich war so verängstigt, dass ich eine Antwort nicht gut genug fand ... weil du 3000 Punkte hast ... Das hat meine Nacht einfach gemacht. :) Danke noch einmal! –

+0

Weiter so! Dieses Zeug scheint zu passieren, auch wenn Sie schon eine Weile programmiert haben: D Manchmal brauchen Sie nur eine kleine Erinnerung für die einfachsten Dinge – James111

2

Sie ändern die Warteschlangenidentität in Reducer nicht. Versuchen Sie diesen Code:

case ADD_ACTION: 
    let queue = state.queue 
    // action.data['completed'] = false 
    queue.push(action.data) 
    console.log("Just updated queue", action.data) 

    return { 
    ...state, 
    queue: [...queue], // <-- here we copy array to get new identity 
    latestAction: new Date() 
    } 

Sie sollten immer flache Kopie geänderte Objets. Siehe http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments

+0

Oder verwenden Sie Slice, wie @ brian-zhou schlug – vovkasm

1

Das Problem ist, dass Sie Ihren Zustand mutieren, wenn Sie dies tun:

let queue = state.queue 
// action.data['completed'] = false 
queue.push(action.data) 

Wenn Sie den bestehenden Zustand direkt mutieren, Redux erkennt keinen Unterschied in Zustand und wird nicht benachrichtigen Sie Komponenten, die das Geschäft geändert hat.

Anstatt also haben Sie die folgenden Optionen ein neues queue Array zu erstellen:

case ADD_ACTION: 
    return { 
    ...state, 
    queue: state.queue.concat(action.data), 
    latestAction: new Date() 
    } 

oder mit ES6 Zucker:

case ADD_ACTION: 
    return { 
    ...state, 
    queue: [...state.queue, action.data] 
    latestAction: new Date() 
    } 
+0

Yep. Ich habe Redux nicht in 2-3 Monaten verwendet, ich muss die Grundlagen wieder auffrischen: '). – James111

1

Eine angeschlossene Komponente hat eine flache Prüfung (===) ob der Status aktualisiert wird und die umbrochene Komponente nur dann wiedergegeben wird, wenn diese Überprüfung fehlschlägt. In Ihrem Fall mutieren Sie Ihre Warteschlange, wodurch die Gleichheit der Prüfung verursacht wird.

Es wird funktionieren, wenn Sie Ihre Minderer wie folgt ändern:

state.queue = state.queue.concat(action.data); 

oder mit ES6 Syntax:

state = { ...state, queue: [...state.queue, action.data] }; 
Verwandte Themen