Redux: How to pass store to form created outside the Provider scope

风格不统一 提交于 2019-12-11 15:26:13

问题


I have written code, which uses a Modal dialog to display a form. My react app is rendered at "root"

index.html

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

App.js

const store = configureStore();

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

ExmpleBasic.js

Please ignore state management in component here. this is just for example.

import React, { PureComponent } from 'react';
import Lorem from 'react-lorem-component';
import Modal from '@atlaskit/modal-dialog';
import Button from '@atlaskit/button';

export default class ExampleBasic extends PureComponent {
  state = { isOpen: false }
  open = () => this.setState({ isOpen: true })
  close = () => this.setState({ isOpen: false })
  secondaryAction = ({ target }) => console.log(target.innerText)

  render() {
    const { isOpen } = this.state;
    const actions = [
      { text: 'Close', onClick: this.close },
      { text: 'Secondary Action', onClick: this.secondaryAction },
    ];

    return (
      <div>
        <Button onClick={this.open}>Open Modal</Button>

        {isOpen && (
          <Modal
            actions={actions}
            onClose={this.close}
            heading="Modal Title"
          >
            <BasicFormContainer />
          </Modal>
        )}
      </div>
    );
  }
}

BasicFormContainer.js

const mapStateToProps = state => ({
  addDesignation: state.designations.addDesignation,
});

const mapDispatchToProps = dispatch => ({
});

export default connect(mapStateToProps, mapDispatchToProps)(BasicForm);

BasicForm.js

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class BasicForm extends Component {
  constructor(props) {
    super(props);
    this.submit = this.submit.bind(this);
  }

  submit(values) {
    console.log(values);
  }

  render() {
    const { handleSubmit } = this.props;

    return (

      <form onSubmit={handleSubmit(this.submit)}>
        <Field
          name="designationName"
          component="input"
          placeholder="Name"
          label="Enter name"
          autoFocus
        />
      </form>

    );
  }
}


export default reduxForm({
  form: 'BasicForm',
  enableReinitialize: true,
})(BasicForm);

However modal is rendered using portal, outside current DOM.

As modal is rendered outside the scope of redux context, it is not getting the store. and i am getting an error "Uncaught Error: Field must be inside a component decorated with reduxForm()"

Below is link to same kind of problem, where redux form within portal is not working. Redux Form Wrapped Inside Custom Portal Component?


回答1:


in React 16 it is handled by portals, but version before then that you can try something like as follow.

export default class ExampleBasic extends PureComponent {
  ...

  static contextTypes = { store: React.PropTypes.object };
  render() {
    const { isOpen } = this.state;
    const actions = [
      { text: 'Close', onClick: this.close },
      { text: 'Secondary Action', onClick: this.secondaryAction },
    ];

    return (
      <div>
        <Button onClick={this.open}>Open Modal</Button>

        {isOpen && (
          <Modal
            actions={actions}
            onClose={this.close}
            heading="Modal Title"
          >
            <Provider store={this.context.store}>
               <BasicFormContainer />
            </Provider>
          </Modal>
        )}
      </div>
    );
    }
  }



回答2:


You need to pass in the values of BasicForm.js to the Redux store and dispatch an action from there itself and not from the BasicFormContainer.js. This way, the Modal remains inside of the scope of your root element and thus there is no need to access the store outside of the Provider.

Then update the Redux store based on the values entered in the form. Once, the store is updated, you can then access it from anywhere in your application such as Modal in your case.




回答3:


I have the same problem. Back to the 2.1.0 version. It worked for me.



来源:https://stackoverflow.com/questions/46950983/redux-how-to-pass-store-to-form-created-outside-the-provider-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!