React Redux 在 Modal 中的使用

IT技术 reactjs redux react-redux
2021-05-25 17:59:35

我正在 React 中学习 Redux。我在 React 中使用 Redux 进行模态开发。我的代码如下

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

(我使用<Provider store={store}>正确吗?)在子组件中,我不能使用 Redux 语法。就像如果我使用它一样,我会export default connect()(EditableRow);收到错误(组件执行未在该组件上完成,执行被阻止)。如果我使用此语法,则export default EditableRow;不会出现任何错误。

可能是我无法正确表达我的问题。

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

我得到低于错误。

在此处输入图片说明

如何在 React Modal 中使用 Redux?

2个回答

这里的问题来自使用React 门户

Portals 提供了一种一流的方式来将子组件渲染到存在于父组件的 DOM 层次结构之外的 DOM 节点中。

Portal 允许在另一个 DOM none 下渲染 React 元素。通过简化,这看起来像

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

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

所以一般ComponentA不会看到ProviderComponentB

您可以查看此页面,但它并未完全描述您所面临的问题。

如果查看<Modal>组件源,它用于React.createPortal呈现自身并失去父级的提供者。

我看到的一种解决方法

  1. store来自合作伙伴的摘录<Provider/>
  2. 使用<Provider>后立即创建新的<Modal>

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

我希望你没有把所有东西都正确地
包裹起来一旦包裹起来,
它就可以在整个应用程序中访问,因为 redux 声明必须有单一的事实来源,
请尽量遵循原则。

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

或者尝试包装你的整个应用程序, 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')
)