Триггерная избыточная форма отправки в componentWillReceiveProps - PullRequest
0 голосов
/ 12 октября 2018

Когда пользователь отправляет форму, я проверяю, изменилось ли значение определенного поля.Если это так, я показываю модальное подтверждение.Если пользователь нажимает «Да» в модальном режиме, модальный компонент устанавливает для свойства «dismissedSubTypeChangeWarning» значение true в избыточном.

Внутри componentWillReceiveProps Я слушаю любые изменения в этом предложении.Если это значение true, я хочу инициировать отправку формы.Я следовал инструкциям на https://redux -form.com / 6.5.0 / examples / remotesubmit / , чтобы настроить это.

Диспетчерский вызов никогда не запускается, потому что в консоли, которую я вижу, «обнаружено»уволить "тогда больше ничего.Я ожидаю увидеть «метод submitForm» после «обнаруженного отклонения».

Я сжал код (ниже) до самой базовой версии, чтобы показать проблему.Когда я запускаю свой код, я не вижу ошибок в консоли.

Я нашел решение, используя ссылки (см. Закомментированную строку), но подделка клика не кажется хорошей практикой.

class ChangeEditForm extends React.Component {
    componentWillReceiveProps (nextProps) {
        if (nextProps.dismissedSubTypeChangeWarning) {
        console.log('detected dismiss')
        this.props.toggleDismissedSubTypeChangeWarning()
        this.props.dispatch(submit('changeEdit'))
        // this.refs.submit.click()
        }
    }

    render () {
        <form onSubmit={this.props.handleSubmit(this.props.submitForm)}>
            <button type='submit' ref='submit'>Save</button>
        </form>
    }
}

const handlers = {
    submitForm: props => (formValues) => {
        console.log('submitForm method')
        if ((formValues.subtype !== props.initialValues.subtype) && !props.dismissedSubTypeChangeWarning) {
            console.log('show warning')
            props.toggleSubTypeChangeConfirmModal()
        } else {
            console.log('submitting form')
        }
    }
}

export function mapStateToProps (state, props) {
    return {
        dismissedSubTypeChangeWarning: state.ui.dismissedSubTypeChangeWarning
    }
}

export default compose(
    pure,
    reduxForm({
        form: 'changeEdit',
        onSubmit: handlers.submitForm
    }),
    connect(mapStateToProps, null),
    withRouter,
    withHandlers(handlers)
)(ChangeEditForm)  

1 Ответ

0 голосов
/ 13 октября 2018

Я все еще думаю, что вы слишком усложняете отправку формы.

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

Создав HOC, мы можем управлять модальным и формой без повторной отправки формы при всплывающем подтверждении.

РаботаПример: https://codesandbox.io/s/lxv9o1nxzl

контейнер / ChangeNameHOC.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { reset } from "redux-form";
import { updateUser } from "../actions";
import { Values } from "redux-form-website-template";
import ChangeNameForm from "./ChangeNameForm";
import ShowModal from "../components/ShowModal";
import CurrentStore from "../containers/CurrentStore";

class ChangeNameHOC extends Component {
  state = {
    modalIsOpen: false,
    formProps: {}
  };

  openModal = () => this.setState({ modalIsOpen: true });

  closeModal = () => this.setState({ modalIsOpen: false });

  validateFormValues = formProps => {
    const { firstName, lastName } = this.props;
    const nextFirstName = formProps.firstName;
    const nextLastName = formProps.lastName;

    if (firstName !== nextFirstName || lastName !== nextLastName) {
      this.setState({ modalIsOpen: true, formProps });
    }
  };

  handleSubmit = () => {
    this.setState({ modalIsOpen: false }, () => {
      this.props.updateUser(this.state.formProps);
      this.props.reset("ChangeNameForm");
    });
  };

  render = () => (
    <div style={{ padding: "0px 20px" }}>
      <ShowModal
        {...this.state}
        {...this.props}
        afterOpenModal={this.afterOpenModal}
        openModal={this.openModal}
        closeModal={this.closeModal}
        handleSubmit={this.handleSubmit}
      />
      <ChangeNameForm validateFormValues={this.validateFormValues} />
      <CurrentStore />
      <Values form="ChangeNameForm" />
    </div>
  );
}

export default connect(
  state => ({
    firstName: state.user.firstName,
    lastName: state.user.lastName
  }),
  { updateUser, reset }
)(ChangeNameHOC);

контейнеров / ChangeNameForm.js

import React from "react";
import { Field, reduxForm } from "redux-form";
import RenderField from "../components/RenderField";

const isRequired = value => (!value ? "Required" : undefined);

const ChangeNameForm = ({
  handleSubmit,
  reset,
  submitting,
  validateFormValues
}) => (
  <form onSubmit={handleSubmit(validateFormValues)}>
    <Field
      className="uk-input"
      label="First Name"
      name="firstName"
      component={RenderField}
      type="text"
      placeholder="First Name"
      validate={[isRequired]}
    />
    <Field
      className="uk-input"
      label="Last Name"
      name="lastName"
      component={RenderField}
      type="text"
      placeholder="Last Name"
      validate={[isRequired]}
    />
    <button
      className="uk-button uk-button-primary"
      type="submit"
      disabled={submitting}
      style={{ marginBottom: 20 }}
    >
      Submit
    </button>
    <div style={{ float: "right" }}>
      <button
        className="uk-button uk-button-danger"
        type="button"
        disabled={submitting}
        onClick={reset}
        style={{ marginBottom: 20 }}
      >
        Reset
      </button>
    </div>
  </form>
);

export default reduxForm({
  form: "ChangeNameForm"
})(ChangeNameForm);

компонентов / ShowModal.js

import React, { PureComponent } from "react";
import Modal from "react-modal";

const customStyles = {
  content: {
    minWidth: "400px",
    top: "50%",
    left: "50%",
    right: "auto",
    bottom: "auto",
    marginRight: "-50%",
    transform: "translate(-50%, -50%)"
  }
};

Modal.setAppElement("#root");

export default class ShowModal extends PureComponent {
  showChange = (name, prevName, nextName) => (
    <div>
      {name}: <strong>{prevName}</strong> to <strong>{nextName}</strong>
    </div>
  );

  render = () => {
    const { firstName, lastName } = this.props;
    const { firstName: nextFirstName } = this.props.formProps;
    const { lastName: nextLastName } = this.props.formProps;

    return (
      <div>
        <Modal
          isOpen={this.props.modalIsOpen}
          onAfterOpen={this.props.afterOpenModal}
          onRequestClose={this.props.closeModal}
          style={customStyles}
          contentLabel="Are you sure?"
        >
          <h3>Are you sure you want to update?</h3>
          <div style={{ marginBottom: 20 }}>
            {firstName !== nextFirstName
              ? this.showChange("FirstName", firstName, nextFirstName)
              : null}
            {lastName !== nextLastName
              ? this.showChange("LastName", lastName, nextLastName)
              : null}
          </div>
          <button
            style={{ float: "left" }}
            className="uk-button uk-button-primary"
            onClick={this.props.handleSubmit}
          >
            confirm
          </button>
          <button
            style={{ float: "right" }}
            className="uk-button uk-button-danger"
            onClick={this.props.closeModal}
          >
            cancel
          </button>
        </Modal>
      </div>
    );
  };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...