首页 文章

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

提问于
浏览
1

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

在应用程序中,我们需要在几个地方显示不同的模态窗口 . 我已经在堆栈溢出中查看了这里的文章,但我无法使其工作 . 我遵循了Dan Abramov在this post描述的过程 .

我的主要问题是我应该在我的应用程序中渲染我的ModalRoot组件 . 过程如下:

  • 我有一个按钮,用于调度动作displayModal以显示模态...
clickHandler: modalProps => (
dispatch(displayModal('MODAL_1', modalProps))

export function displayModal(modalType, modalProps) {
  return {
    type: DISPLAY_MODAL,
    payload: {
      modalType,
      modalProps
    }
  };
}
  • 然后该操作由reducer处理,该reducer将modalType属性设置为redux-state ...
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;
  }
}
  • 然后我有ModalRootContainer将状态传递给我的ModalRoot组件......
const mapStateToProps = state => (
  {
    modalType: modalState(state).get('modalType'),
    modalProps: modalState(state).get('modalProps')
  }
);

const ModalRootContainer =
  connect(mapStateToProps)(ModalRoot);

export default ModalRootContainer;
  • 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应该放在哪里?在Provider标签内?我错过了什么?

Edit 1 :我正在尝试使用随机用户在下面的答案中所说的内容,但没有效果 . 所以我在我的index.html:

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

在我的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')
    );

并且通过以上所有设置仍然没有显示模态 . 我调试,我看到动作被触发,状态从reducer更新 . 有没有办法在这一点之后调试以查看我的容器是否有问题以及为什么模态没有显示?

Edit 2 :我发现了什么问题 . 我错误地将状态传递给了我的容器 . 代码似乎工作,但现在,而不是有一个模态窗口显示,我有我的组件(应该在模态内)出现在我的剩余页面上方 . 我只是渲染一个简单的文本"Close modal"和一个关闭它的按钮 . 它被正确显示和隐藏但它不能作为模态,它只是显示和隐藏 . 对我失踪的任何帮助?

Hidden:

Shown:

2 回答

  • 1

    你应该在当前的 Provider 中渲染 ModalRootContainer . 你可能有一些带 <Provider> ... </Provider>app.js 文件 . 这是您应该渲染容器的地方 .

    这是因为 redux 通过上下文共享状态(https://facebook.github.io/react/docs/context.html) . Provider 是创建该上下文的组件,并且由于 connect ,您在props中拥有其数据 . 因此,要访问state,必须将所有容器渲染为 Provider 组件的子/孙子/ ....

  • 1

    您已声明 ModalRootComponent 但实际使用它必须在应用程序中的某处呈现它 . 我的意思是渲染就是把它放在内部做出反应 ReactDOM.render(...) 函数 .

    当您使用redux时,渲染函数通常看起来像这样,并且在所有内容之上使用 Provider 标记:

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

    你可以做什么来渲染 ModalRootContainer 组件只是将它放在Provider标签内,如下所示:

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

    但是在更复杂的情况下,您可以在这里渲染路由器,然后在每条路径中实际执行内容:

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

    还要确保您已正确设置redux存储,并且它知道您的减速器 . 你可以看到react和redux here的工作todo示例 .

相关问题