在React中获取并使用响应来更改状态

时间:2020-01-29 13:35:25

标签: reactjs formik

我想根据使用react-refetch的PUT请求的响应来更改组件的状态。

特别是当PUT的响应不成功时,例如500响应。

以下示例是形式示例。用户提交表单后,应触发PUT。

如果满足PUT响应,则应重置表格。否则,什么都不会发生,并且用户应该能够重试。

./ MyForm.jsx

import React from "react";
import PropTypes from "prop-types";
import { PromiseState } from "react-refetch";
import { Formik, Form, Field, ErrorMessage } from "formik";
import ResetOnSuccess from "./ResetOnSuccess";

const MyForm = ({ settingsPut, settingsPutResponse }) => {
  const submitForm = (values, formik) => {
    settingsPut(true);

    // Here it should pick up the settingsPutResponse,
    // and then do the following ONLY if it's successful:
    //
    // formik.resetForm({ values });
    // window.scrollTo(0, 0);
  };

  return (
    <div>
      <Formik
        noValidate
        initialValues={{ name: "", password: "" }}
        onSubmit={submitForm}
      >
        {({ dirty }) => (
          <Form>
            <ResetOnSuccess settingsPutResponse={settingsPutResponse} />
            <Field type="text" name="name" />
            <ErrorMessage name="name" component="div" />
            <Field type="password" name="password" />
            <ErrorMessage name="password" component="div" />
            <button type="submit" disabled={dirty !== null ? !dirty : false}>
              Submit
            </button>
            {settingsPutResponse && settingsPutResponse.rejected && (
              <p style={{ color: "red" }}>Please try again</p>
            )}
          </Form>
        )}
      </Formik>
    </div>
  );
};

MyForm.propTypes = {
  settingsPut: PropTypes.func.isRequired,
  settingsPutResponse: PropTypes.instanceOf(PromiseState)
};

MyForm.defaultProps = {
userSettingsPutResponse: null
};

export default MyForm;

我可能会通过创建一个组件来解决问题:

。/ResetOnSuccess.jsx

import React, { useEffect, useState } from "react";
import { useFormikContext } from "formik";
import PropTypes from "prop-types";
import { PromiseState } from "react-refetch";

const ResetOnSuccess = ({ settingsPutResponse }) => {
  const { values, resetForm } = useFormikContext();
  const [success, setSuccess] = useState(false);

  useEffect(() => {
    if (settingsPutResponse && settingsPutResponse.fulfilled) {
      setSuccess(true);
    }
  }, [settingsPutResponse]);

  // only if settingsPutResponse is fulfilled will it reset the form
  if (success) {
    resetForm({ values });
    window.scrollTo(0, 0);
    setSuccess(false);
  }

  return null;
};

ResetOnSuccess.propTypes = { settingsPutResponse: PropTypes.instanceOf(PromiseState) };
ResetOnSuccess.defaultProps = { settingsPutResponse: null };

export default ResetOnSuccess;

然后在 ./ MyForm.jsx 中添加重置组件:

<Formik
  noValidate
  initialValues={{ name: "", password: "" }}
  onSubmit={submitForm}
>
  {({ dirty }) => (
    <Form>
      <ResetOnSuccess settingsPutResponse={settingsPutResponse} />
      <Field type="text" name="name" />
      <ErrorMessage name="name" component="div" />
      <ResetOnSuccess settingsPutResponse={settingsPutResponse} />
      // etc...

但是由于它是一个返回“ null”的组件。感觉有点像反模式。

有更好的方法吗?

我在此处创建了一个codeandbox示例:https://codesandbox.io/s/quizzical-johnson-dberw

0 个答案:

没有答案