Reactjs 使用无状态功能组件在react redux中创建模态

Reactjs 使用无状态功能组件在react redux中创建模态,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我们正在React Redux中实现一个应用程序,其中包含无状态功能组件和容器,用于处理状态。其想法是将所有信息都保存在Redux存储中 在应用程序中,我们需要在几个地方显示不同的模式窗口。我已经在stack overflow中查看了这里的文章,但我无法使其正常工作。我遵循了丹·阿布拉莫夫在书中描述的过程 我的主要问题是应该在应用程序中的何处呈现ModalRoot组件。过程如下: 我有一个按钮,调度一个动作显示模式,以便显示一个模式 clickHandler: modalProps => ( d

我们正在React Redux中实现一个应用程序,其中包含无状态功能组件和容器,用于处理状态。其想法是将所有信息都保存在Redux存储中

在应用程序中,我们需要在几个地方显示不同的模式窗口。我已经在stack overflow中查看了这里的文章,但我无法使其正常工作。我遵循了丹·阿布拉莫夫在书中描述的过程

我的主要问题是应该在应用程序中的何处呈现ModalRoot组件。过程如下:

  • 我有一个按钮,调度一个动作显示模式,以便显示一个模式

    clickHandler: modalProps => ( dispatch(displayModal('MODAL_1', modalProps)) export function displayModal(modalType, modalProps) { return { type: DISPLAY_MODAL, payload: { modalType, modalProps } }; } clickHandler:modalProps=>( 调度(显示模式('MODAL_1',modalProps)) 导出函数displayModal(modalType、modalProps){ 返回{ 类型:显示模式, 有效载荷:{ modalType, 莫达尔普洛斯 } }; }
  • 然后该操作由一个reducer处理,该reducer将modalType属性设置为redux状态

    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; } } 导出默认函数(modal=Map(),操作){ 如果(!操作){ 返回模式; } 开关(动作类型){ 案例显示模式: 返回模式 .set('modalType',action.payload.modalType) .set('modalProps',action.payload.modalProps'); 违约: 返回模式; } }
  • 然后我有一个ModalRootContainer,它将状态传递给我的ModalRoot组件

    const mapStateToProps = state => ( { modalType: modalState(state).get('modalType'), modalProps: modalState(state).get('modalProps') } ); const ModalRootContainer = connect(mapStateToProps)(ModalRoot); export default ModalRootContainer; 常量mapStateToProps=状态=>( { modalType:modalState(state).get('modalType'), modalProps:modalState(state).get('modalProps') } ); 常量ModalRootContainer= 连接(MapStateTops)(ModalRoot); 导出默认ModalRootContainer;
  • ModalRootComponent如下所示:

    const ModalRoot = (modalType, modalProps) => { if (!modalType) { return <span />; } switch (modalType) { case 'MODAL_1': return <MyComponent {...modalProps}/>; default: return <span />; } }; ModalRoot.propTypes = { modalType: PropTypes.string, modalProps: PropTypes.object }; export default ModalRoot; 常量ModalRoot=(modalType,modalProps)=>{ if(!modalType){ 返回<span/>; } 开关(modalType){ 案例“模态_1”: return<MyComponent{…modalProps}/>; 违约: 返回<span/>; } }; ModalRoot.propTypes={ modalType:PropTypes.string, modalProps:PropTypes.object }; 导出默认ModalRoot;
  • 我的理解是这是正确的,但它不起作用。ModalRoot应该放在哪里?在Provider标记内?我缺少什么

    编辑1: 我试图使用随机用户在下面的答案中所说的内容,但没有任何效果。因此,我在index.html中:

    <body>
    <div id="modals"></div>
    <div id="root"></div>
    </body>
    
    
    
    在my main.js中:

    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')
        );
    
    ReactDOM.render(
    {路由(存储)}
    ,
    document.getElementById('root'))
    );
    ReactDOM.render(
    ,
    document.getElementById('modals'))
    );
    
    在所有上述设置中,仍然没有显示任何模式。我调试并看到操作已触发,并且状态已从减速器中更新。是否有方法在此之后进行调试,以查看我的容器是否有问题,以及为什么没有显示模式

    编辑2:我发现了问题所在。我错误地将状态传递给了容器。代码似乎正常工作,但是现在我没有显示模式窗口,而是让我的组件(应该在模式中)显示在剩余页面的上方。我现在只是呈现一个简单的文本“关闭模式”和一个按钮来关闭它。它被正确地显示和隐藏,但它不作为一个模态工作,它只是显示和隐藏。有什么帮助我失踪


    您应该在当前的
    提供商
    中呈现
    ModalRootContainer
    。您可能有一些
    app.js
    文件,里面有
    。这是您应该呈现容器的地方


    这是因为
    redux
    通过上下文共享状态().
    Provider
    是一个创建该上下文的组件,多亏了
    connect
    ,您才有了道具中的数据。因此,要访问state,您必须将所有容器呈现为
    Provider
    组件的子/孙辈/。

    您已经声明了一个
    ModalRootComponent
    ,但要实际使用它,您必须重新呈现我所说的渲染是将它放在reacts
    ReactDOM.render(…)
    函数中

    当您使用redux时,渲染功能通常如下所示,在所有内容的顶部都有
    Provider
    标记:

    ReactDOM.render(
      <Provider store={store}>
    
        ...
    
      </Provider>,
      document.getElementById('root')
    );
    
    但在更复杂的场景中,您将在此处渲染路由器,然后在每条路由内实际执行内容:

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

    还要确保您已经正确设置了redux存储,并且它知道您的reducer。您可以看到react和redux的todo示例。

    对于modals,我认为最好在html文档中创建一个新节点/div,并将该组件放在那里
    ReactDOM.render(,document.getElementById('modals'));
    虽然整个应用程序可以在单独的文档节点中呈现。这将允许您根据需要设置模型的样式,并且不会影响
    的结构/用户界面。您还可以使用它显示加载消息、警报,这将作为不同类型用户界面的附加层。好的,但是当我已经有了e:
    ReactDOM.render({routing(store)},document.getElementById('root'))
    只需在下面添加一个新的
    ReactDOM.render
    ,您可以调用
    ReactDOM.render
    任意次数。除非
    Modals
    是您整个应用程序不可或缺的一部分,否则我建议您使用一些提供Modals的现有库。您可以放置其他代码,如
    ReactDOM.render(,document.getElementById('modals');
    谢谢。我遇到了您提到的路由的第二个案例。在这种情况下,我的ModalContainer应该去哪里?我在执行以下操作时遇到错误:“React.Children.只希望收到一个React元素子级。”
    ReactDOM.render(
      <Provider store={store}>
    
        <Router history={history}>
          {routes}
        </Router>
    
      </Provider>,
      document.getElementById('root')
    );