2017-09-12 14 views
0

私は、ディスプレイ "状態"を維持する接続されたコンポーネントと、2つのコンポーネント間の通信に必要な他のいくつかのものを持っています。私は、このオーバーアーチ型コンポーネントの子である2つの接続されたコンポーネントを持っています。 「状態」コンポーネント内のフラグに応じて、一方または他方の子コンポーネントがレンダリングされる。React Redux mapStateToPropsが更新時に起動しない

EditorStateコンポーネント:

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アクション:

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リデューサー:

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

ライブラリコンポーネント:

単にコードを表示するには良いかもしれません
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); 

ライブラリアクション:

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

ライブラリリデューサー:

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

私が午前の問題は、ライブラリコンポーネントでmapStateToPropsがLIBRARY_INITIALIZEの発送時に呼び出されていないということです。 EditorStateとLibraryのmapStateToPropsとLibrary reducerのLIBRARY_INITIALIZEスイッチのブレークポイントの両方にブレークポイントがあります。デバッグページの読み込みはこのように書きます:

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

ライブラリmapStateToProps - - state.LibraryReducer.templates state.EditorStateReducer.stateは

EditorState mapStateToProps nullです== []

ライブラリ減速初期化 - action.templates == [{template1を}、{template2}等]

EditorState mapStateToProps - state.LibraryReducer.templates == [{template1}、{template2}など]

何もしません。ライブラリのmapStateToPropsも起動するので、ライブラリでテンプレートを再レンダリングすることができます。しかし、これは起こっていません。なぜこれは起こっていないのですか?私はこの上に私の髪を引き出す準備ができています...

答えて

2

ディスパッチコール直後に更新された状態がレンダリングされることを100%保証することはできません。 mapStatetoPropsは、コンポーネントが再レンダリングしようとするときに呼び出されます。これは、Reactが更新をバッチ処理するかどうかによって異なります。デフォルトでは、Reactはイベントハンドラから更新をバッチします。

あなたは、その場合は、なぜEditorState mapStateToPropsは発送後解雇と私は必要な正しい減速中のデータを持っていることになるhttps://github.com/reactjs/react-redux/issues/291

+0

を参照することができますか? mapStateToPropsはディスパッチ時にすべてのサブスクライバに対して呼び出されるため、Reactが再レンダリングするかどうかを判断できるように小道具を更新できます。それは別の方法ではありません。 ご協力いただきありがとうございますが、これは正しくありません。そうだった場合、ReduxはReactで正常に動作しませんでした。 この質問で回答したmarkeriksonを参照できます:https://stackoverflow.com/questions/41646353 – light

+0

あなたのリンクの質問に誰が回答しているかを見て、もう少し実験を行いました。 libraryInitialize変数をLibraryReducerに追加し、次にEditorStateのcomponentWillReceiveの小道具で、新しいlibraryInitializeが古いものと等しくなかった場合にthrowアクションを送出しました。確かに、ライブラリのmapStateToPropsは正しいテンプレート値で起動します。私はそれがまさにそれだったので、これを受け入れられた答えとしてマークしています。しかし、これはReduxが階層的に接続されたコンポーネントをうまく扱わないという厳しい制限のようです。 – light

+0

私は同じ問題があったとき、それは本当です。私が見つけたのは、従属行為を発射したことが、一種の反パターンであることです。可能な限り、あなたの従属アクションをクラブにし、できるだけリデューサーに多くのビジネスロジックを置く必要があります。私はこれが理にかなってほしい。 –

関連する問題