Использование React Redux в Модале - PullRequest
2 голосов
/ 22 мая 2019

Я изучаю Redux в React. Я использую Redux в React для модальной разработки. Мой код как показано ниже

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

Я получаю ошибку ниже.

enter image description here

Как использовать Redux в React Modal?

Ответы [ 2 ]

3 голосов
/ 23 мая 2019

Проблема здесь возникает из-за использования React порталов

Порталы предоставляют первоклассный способ рендеринга дочерних элементов в узел DOM, который существует вне иерархии DOM родительского компонента..

Портал позволяет отображать элементы React под другим DOM none.С упрощениями это будет выглядеть как

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

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

Так что в общем ComponentA не будет видеть Provider из ComponentB.

Вы можете посмотреть на этой странице , однако он не полностью описывает проблему, с которой вы столкнулись.

Если посмотреть на <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>
    
1 голос
/ 31 мая 2019

Надеюсь, вы не все правильно завернули,
однажды обернутый, доступный через приложение,
в качестве избыточных состояний должен быть единственный источник правды,
старайтесь следовать принципам.

// 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')
)
...