简体   繁体   English

React Redux在Modal中的使用

[英]Usage of React Redux in Modal

I am learning Redux in React. 我正在React中学习Redux。 I am using Redux in React for Modal development. 我在React中使用Redux进行模态开发。 My code is like below 我的代码如下

render() {
    return (
      <Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}>
        <Provider store={store}>
          {this.props.addresObj ? (
            <Modal.Header>Address Details</Modal.Header>
          ) : (
            <Modal.Header>Insert Address</Modal.Header>
          )}
          <Modal.Content>
              <ModalElement
                update={this.update}
                element={this.props.addresObj}
                errors = {this.state.errors}
                update_state_photo={this.update_state_photo}
                address={this.props.address}
                action={this.props.action}
              />
          </Modal.Content>

          <Modal.Actions>
            {this.props.addresObj ? (
              <Button
                positive
                icon="checkmark"
                labelPosition="right"
                onClick={this.closeModal}
                content="OK"
              />
            ) : (
              <Button
                positive
                icon="checkmark"
                labelPosition="right"
                onClick={this.insertAddress}
                content="Save"
              />
            )}
          </Modal.Actions>
        </Provider>
      </Modal>
    );
  }
}

(Did I use <Provider store={store}> properly ?) In child component I can't use Redux syntax. (我是否正确使用了<Provider store={store}> ?)在子组件中,我无法使用Redux语法。 Like if I use this export default connect()(EditableRow); 就像如果我使用此export default connect()(EditableRow); I am getting error (component execution is not finish at that component, execution forwared). 我收到错误消息(该组件的执行尚未完成,需要执行)。 If I use this syntax export default EditableRow; 如果使用此语法,请export default EditableRow; I am not getting any error. 我没有任何错误。

May be I could not express my issue properly. 可能是我无法正确表达我的问题。

Here is my repo https://github.com/afoysal/mern/blob/master/client/src/components/ModalBody.js 这是我的仓库https://github.com/afoysal/mern/blob/master/client/src/components/ModalBody.js

I am getting below error. 我正在错误以下。

在此处输入图片说明

How to use Redux in React Modal ? 如何在React Modal中使用Redux?

The problem here arise from using React portals 这里的问题来自使用React门户

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. 门户网站提供了一种一流的方式来将子级呈现到父组件的DOM层次结构之外的DOM节点中。

Portal allows to render React elements under another DOM none. 门户允许在另一个DOM下不呈现React元素。 With simplifications this will look like 经过简化,这看起来像

const ComponentA = ReactDOM.createPortal(
    <CoolComponent />,
    document.getElementById('banner'),
)

const ComponentB = ReactDOM.createPortal(
    <SuperCoolComponent />,
    document.getElementById('footer'),
)

So in gneral ComponentA will not see Provider of ComponentB . 因此,在一般情况下, ComponentA将看不到ComponentB Provider

You may look at this page , however it does not fully describe problem you faced. 您可能会看到此页面 ,但是它不能完全描述您遇到的问题。

If look to <Modal> component source, it uses React.createPortal to render itself and looses parent's provider. 如果查看<Modal>组件源,它将使用React.createPortal呈现自身并失去父级的提供者。

One workaround I see 我看到的一种解决方法

  1. Extract store from partner's <Provider/> 从合作伙伴的<Provider/>提取store
  2. Create new <Provider> just after <Modal> usage. 在使用<Modal>之后立即创建新的<Provider>

     // ModelBody.js import { Provider, ReactReduxContext } from 'react-redux'; //... render() { return ( <ReactReduxContext.Consumer> {((ctx) => ( <Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}> <Provider store={ctx.store}> /* make store available in Portal */ {this.props.addresObj ? ( <Modal.Header>Address Details</Modal.Header> ) : ( <Modal.Header>Insert Address</Modal.Header> )} /* other code from Model.js */ </Provider> </Modal> )).bind(this) // Dont forget to bind this } </ReactReduxContext.Consumer> 

i hope you didn't wrap everything inside properly, 我希望你没有把所有东西都包好,
once wrapped, its accessible throughout the app, 打包后,可在整个应用程序中访问
as redux states there must be single source of truth, 正如redux所说,必须有单一的真理来源,
do try to follow principles. 一定要遵循原则。

// ModelBody.js
import { Provider, ReactReduxContext } from 'react-redux';

//...
render() {
    return (

        <ReactReduxContext.Consumer>
            {((ctx) => (
         <Provider store={ctx.store}>
                <Modal id="addressModal" open={this.props.controlModal} onClose={this.props.action}>
                      /* make store available in Portal */
                        {this.props.addresObj ? (
                            <Modal.Header>Address Details</Modal.Header>
                        ) : (
                            <Modal.Header>Insert Address</Modal.Header>
                        )}
                    /* other code from Model.js */

                </Modal>
           </Provider>
           )).bind(this) // Dont forget to bind this
       }
   </ReactReduxContext.Consumer>

or try to wrap your whole app, index.jsx 或尝试包装整个应用程序index.jsx

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './components/App'

const store = createStore(rootReducer)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM