Получить и использовать ответ для изменения состояния в React - PullRequest
0 голосов
/ 29 января 2020

Я хотел бы изменить состояние компонента на основе ответа на запрос PUT, используя response-refetch .

Особенно, когда ответ на 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'. Это немного похоже на анти-шаблон.

Есть ли лучший способ?

Я создал здесь пример кода и коробки: https://codesandbox.io/s/quizzical-johnson-dberw

...