2017-09-12 12 views
0

Ich habe eine verbundene Komponente, die einen Anzeige- "Zustand" zusammen mit einigen anderen Dingen aufrechterhält, die für die Kommunikation zwischen einigen Komponenten benötigt werden. Ich habe zwei verbundene Komponenten, die Kinder dieser übergreifenden Komponente sind. Abhängig von einem Flag, das sich innerhalb der "state" -Komponente befindet, wird die eine oder andere untergeordnete Komponente gerendert. Es könnte besser sein, nur den Code zeigen:React Redux mapStateToProps löst keine Aktualisierung aus

EditorState Komponente:

import React from 'react'; 
import {connect} from 'react-redux'; 

import Library from '../library/index'; 
import Editor from '../editor/index'; 

import { 
    initialize, 
    editorState 
} from './actions'; 

class EditorState extends React.Component { 
    componentWillMount() { 
    const {dispatch} = this.props; 
    dispatch(initialize()); 
    } 

    render() { 
    const {state} = this.props; 
    switch(state) { 
     case editorState.Library: 
     return <Library /> 
     case editorState.Editor: 
     return <Editor /> 
     default: 
     return null; 
    } 
    } 
} 

export default connect(state => { 
    return state.EditorStateReducer; 
})(EditorState); 

EditorState Aktionen:

export const EDITOR_STATE_INITIALIZE = 'EDITOR_STATE_INITIALIZE'; 

export const editorState = { 
    Library: 'library', 
    Editor: 'editor' 
} 

export const initialize = ({ 
    type: EDITOR_STATE_INITIALIZE, 
    state: editorState.Library 
}); 

EditorState Reducer:

import { 
    EDITOR_STATE_INITIALIZE 
} from './actions'; 

const init =() => ({ 
    state: null 
}); 

export default (state = init(), action) => { 
    switch(action.type) { 
    case EDITOR_STATE_INITIALIZE: 
     return { 
     ...state, 
     state: action.state 
     } 
    default: 
     return {...state} 
    } 
} 

Bibliothek Komponente:

import React from 'react'; 
import {connect} from 'react-redux'; 

import {Page} from '../../../components/page/index'; 

import LibraryItem from '../../../components/library-item/library-item'; 

import { 
    initialize 
} from './actions'; 

class Library extends React.Component { 
    componentWillMount() { 
    const {dispatch} = this.props; 
    dispatch(initialize()); 
    } 

    render() { 
    const {templates} = this.props; 

    const editorTemplates = templates.map(template => 
     <LibraryItem template={template} /> 
    ); 

    return (
     <Page> 
     <div className="card-flex library-table"> 
      {editorTemplates} 
     </div> 
     </Page> 
    ) 
    } 
} 

export default connect(state => { 
    return state.LibraryReducer; 
})(Library); 

Bibliothek Aktionen:

import { 
    client, 
    serviceUrl 
} from '../../../common/client'; 

export const LIBRARY_INITIALIZE = 'LIBRARY_INITIALIZE'; 

export const initialize =() => dispatch => { 
    client.get(`${serviceUrl}/templates`).then(resp => { 
    dispatch({ 
     type: LIBRARY_INITIALIZE, 
     templates: resp.templates 
    }); 
    }); 
} 

Bibliothek Reducer:

import { 
    LIBRARY_INITIALIZE 
} from './actions'; 

const init =() => ({ 
    templates: [] 
}); 

export default (state = init(), action) => { 
    switch(action.type) { 
    case LIBRARY_INITIALIZE: 
     return { 
     ...state, 
     templates: action.templates 
     } 
    default: 
     return {...state} 
    } 
} 

Das Problem, das ich habe, ist, dass die mapStateToProps in der Bibliothek Komponente ist nicht auf den Versand von LIBRARY_INITIALIZE aufgerufen wird. Ich habe Haltepunkte in beiden MapStateToProps in EditorState und Bibliothek und einen Haltepunkt in dem LIBRARY_INITIALIZE-Schalter in dem Bibliotheksreduzierer. Debugging Seite zu laden geht so:

EditorState mapStateToProps - state.EditorStateReducer.state ist null

EditorState mapStateToProps - state.EditorStateReducer.state == editorState.Library

Bibliothek mapStateToProps - state.LibraryReducer.templates == []

Bibliothek Reducer initialisieren - action.templates == [{template1}, {} template2, etc]

EditorState mapStateToProps - state.LibraryReducer.templates == [{template1}, {template2}, usw.]

Dann nichts. Ich würde erwarten, dass die Bibliothek mapStateToProps danach ebenfalls ausgelöst wird, damit die Bibliothek mit den Vorlagen erneut rendern kann. Dies geschieht jedoch nicht. Warum passiert das nicht? Ich bin bereit, meine Haare über diese zu ziehen ...

Antwort

2

Sie können nicht 100% sicher sein, dass der aktualisierte Zustand direkt nach dem Dispatch-Aufruf gerendert wird. mapStatetoProps wird aufgerufen, wenn die Komponente im Begriff ist, erneut zu rendern, was davon abhängt, ob React die Aktualisierungen stapelt oder nicht. React führt standardmäßig Aktualisierungen von Ereignishandlern durch.

können Sie https://github.com/reactjs/react-redux/issues/291

+0

verweisen Wenn das der Fall ist, dann würde, warum das EditorState mapStateToProps nach dem Versand abgefeuert werden und die Daten in den richtigen Minderer haben, die ich brauche? mapStateToProps wird für jeden Abonnenten nach einem Versand aufgerufen, sodass die Requisiten aktualisiert werden können, sodass React bestimmen kann, ob es erneut rendern soll oder nicht. Es ist nicht umgekehrt. Ich weiß es zu schätzen, dass Sie versuchen zu helfen, aber das ist nicht korrekt. Wenn dies der Fall wäre, würde Redux mit React nicht richtig funktionieren. Sie können auf die Antwort hinweisen, die markerikson in dieser Frage gab: https://stackoverflow.com/questions/41646353 – light

+0

So machte ich einige mehr experimentieren auf zu sehen, wer die Frage in Ihrem Link beantwortete. Ich habe dem LibraryReducer eine libraryInitialize-Variable hinzugefügt und dann in den componentWillReceive-Requisiten auf EditorState eine Wegwerfaktion ausgelöst, wenn das neue libraryInitialize nicht dem alten entspricht. Tatsächlich wird das MapStateToProps in der Bibliothek mit den richtigen Vorlagenwerten ausgelöst. Ich bezeichne dies als die akzeptierte Antwort, weil es genau das war. Dies scheint jedoch eine schwerwiegende Einschränkung von Redux zu sein, nicht mit hierarchisch verbundenen Komponenten umzugehen. – light

+0

Ja, das stimmt, als ich das gleiche Problem hatte. Was ich gefunden hatte, war das Abfeuern von abhängigen Aktionen. Sie sollten Ihre abhängigen Aktionen zusammenfassen und so viel Geschäftslogik wie möglich in Reducer setzen, als einen zu entlassen und darauf zu warten, dass Requisiten herunterfließen, um die abhängige Aktion auszulösen. Ich hoffe das macht Sinn. –

Verwandte Themen