2017-02-16 4 views
1

を使用して反応させ、Reduxのでモーダルを作成します。 React-Reduxでは、状態を処理する必要のあるステートレス機能コンポーネントとコンテナを使用してアプリケーションを実装しています。アイデアは、すべての情報をReduxストアに保存することです。我々はいくつかの場所別のモーダルウィンドウに表示する必要があるアプリケーションでIが反応-Reduxのをするので、私と一緒に裸してください新しいですステートレス機能部品に

。私はここでスタックオーバーフローの記事を調べましたが、私はこれを得ることができません。私はダン・アブラモフが記述したプロセスを、this postに従っています。

私の主な質問は、私は自分のアプリケーション内で私のModalRootコンポーネントをレンダリングする必要がある場所です。このプロセスは以下の通りである。

  1. 私はモーダルを表示するために、アクションdisplayModalをディスパッチするボタンを持っている...

     
    clickHandler: modalProps => (
    dispatch(displayModal('MODAL_1', modalProps)) 
    
    export function displayModal(modalType, modalProps) { 
        return { 
        type: DISPLAY_MODAL, 
        payload: { 
         modalType, 
         modalProps 
        } 
        }; 
    } 
    
  2. 次にアクションが設定減速によって処理されますそれから私は私のModalRootコンポーネントに状態を渡しModalRootContainerをReduxの状態でmodalTypeプロパティ...

     
    export default function (modal = Map(), action) { 
        if (!action) { 
        return modal; 
        } 
        switch (action.type) { 
        case DISPLAY_MODAL: 
         return modal 
         .set('modalType', action.payload.modalType) 
         .set('modalProps', action.payload.modalProps); 
        default: 
         return modal; 
        } 
    } 
    
  3. を持っている...

     
    const mapStateToProps = state => (
        { 
        modalType: modalState(state).get('modalType'), 
        modalProps: modalState(state).get('modalProps') 
        } 
    ); 
    
    const ModalRootContainer = 
        connect(mapStateToProps)(ModalRoot); 
    
    export default ModalRootContainer; 
    
  4. 次のようにModalRootComponentは次のとおりです。

     
    const ModalRoot = (modalType, modalProps) => { 
        if (!modalType) { 
        return &ltspan />; 
        } 
    
        switch (modalType) { 
        case 'MODAL_1': 
         return &ltMyComponent {...modalProps}/>; 
        default: 
         return &ltspan />; 
        } 
    }; 
    
    ModalRoot.propTypes = { 
        modalType: PropTypes.string, 
        modalProps: PropTypes.object 
    }; 
    
    export default ModalRoot; 
    

私の理解では、これは正しいですが、それが動作しないということです。どこにModalRootを置くべきですか?プロバイダタグの中に?私は何が欠けていますか?

編集1: ランダムユーザーが以下の答えで何を言っているかは、何の効果もありません。だから、私はindex.htmlの中に持っている:私のmain.jsで

<body> 
<div id="modals"></div> 
<div id="root"></div> 
</body> 

ReactDOM.render(
     <Provider store={store}> 
     <Router history={hashHistory}>{routing(store)}</Router> 
     </Provider>, 
     document.getElementById('root') 
    ); 
    ReactDOM.render(
     <Provider store={store}> 
     <ModalRootContainer /> 
     </Provider>, 
     document.getElementById('modals') 
    ); 

そして、上記のすべての設定まだモーダルが示さされていないと。私はデバッグし、私はアクションがトリガされ、状態が減速機から更新されることがわかります。私のコンテナに何か問題があり、なぜモーダルが表示されていないのかを確認するために、この時点以降にデバッグする方法はありますか?

編集2:私が間違っていたものを発見しました。私は間違ってコンテナに状態を渡していた。コードは、しかし、今の代わりにモーダルウィンドウのショーを有するので、私は(モーダル内のことになって)私のコンポーネントを過ごしています、私の残りのページ上に表示され、動作しているようです。私はその時点で単純なテキスト「閉じるモーダル」とそれを閉じるためのボタンをレンダリングしています。これは正しく表示され、隠されていますが、モーダルとしては機能しません。表示され、隠されます。私が逃しているものについての助け?

Hidden:

Shown:

+1

私は、あなたのhtmlドキュメントに新しいノード/ divを作成し、そこにそのコンポーネントを置くのが最善の方法だと思います。ReactDOM.render(、document.getElementById( 'modals')); 'アプリ全体は別のドキュメントノードでレンダリングできますが、これにより、モデルのスタイルを自由に変えることができ、 ''の構造やUIには影響しません。これを使用して、メッセージ、アラートの読み込みを表示することもできます。これは、さまざまなタイプのUIに対して追加のレイヤーとして機能します。 –

+0

OKこれは私が既に持っている場合に起こる方法: 'ReactDOM.render( <プロバイダストア= {ストア}> <ルータ履歴= {hashHistory}> {ルーティング(店舗)} 、 のdocument.getElementById( 'root') ); ' – empyreal

+0

' ReactDOM.render'を追加するだけで、 'ReactDOM.render'を何度でも呼び出すことができます。' Modals'があなたのアプリケーション全体の不可欠な部分でない限り、私はModalsを提供する既存のライブラリを使用することをお勧めします。 'ReactDOM.render(、document.getElementById( 'modals')); ' –

答えて

1

あなたの現在のProviderModalRootContainerをレンダリングする必要があります。おそらく、内部<Provider> ... </Provider>といくつかのapp.jsファイルを持っています。これはコンテナをレンダリングする場所です。

reduxは、状態(https://facebook.github.io/react/docs/context.html)を共有しているためです。 Providerはそのコンテキストを作成するコンポーネントであり、connectのおかげであなたはそのデータを小道具に持っています。状態にアクセスするには、すべてのコンテナをProviderの子/孫/子としてレンダリングする必要があります。

1

あなたはModalRootComponentを宣言しましたが、実際にはそれをアプリケーションのどこかにレンダリングする必要があります。私がレンダリングを意味するのは、内部に置くことです。ReactDOM.render(...)の機能に反応します。

あなたのレンダリング機能をReduxの使用している通常のすべての上にProviderタグを次のようになります。あなたがModalRootContainerコンポーネントをレンダリングするために何ができるか

ReactDOM.render(
    <Provider store={store}> 

    ... 

    </Provider>, 
    document.getElementById('root') 
); 

はちょうどプロバイダタグの中にそれを置くことです

ReactDOM.render(
    <Provider store={store}> 

    <ModalRootContainer /> 

    </Provider>, 
    document.getElementById('root') 
); 

しかし、より複雑なシナリオでは、あなたが実際にコンテンツを行うだろう、各ルートの内側にここにして、ルータをレンダリングして行くだろう:

このような3210
ReactDOM.render(
    <Provider store={store}> 

    <Router history={history}> 
     {routes} 
    </Router> 

    </Provider>, 
    document.getElementById('root') 
); 

また、あなたはredux store rightを設定していて、あなたのレデューサーについて知っていることを確認してください。あなたは、反応して還元するhereと働いているtodoの例を見ることができます。

+0

のような追加コードを配置することができます。私はあなたがルーティングと言及する2番目のケースを持っています。この場合、私のModalContainerはどこに行きますか?私はエラーが発生しています:「反応する。児童はただ1つの反応要素の子を受け取ることしか期待していない。次の操作を行っている間:ReactDOM.render( <プロバイダストア= {店}> <ルータ履歴= {hashHistory}> {ルーティング(店舗)} 、 のdocument.getElementById( 'ルート' を) ); – empyreal

+1

@empyreal thats ** **はその中に子ノードが1つしかないと予想していますので、そのコンテンツを

...
またはその他のカスタムコンポーネント内にラップする必要があります。 patotoma

+0

ありがとうございます。 '

'は私のページに最初にモーダルの内容を表示し、次に残りのアプリケーションを各ページに表示しませんか?それでもまだ動作していません。私は何かが足りない。 – empyreal

関連する問題