为什么asyncValidate不以Redux形式传递错误?

时间:2018-03-19 05:57:26

标签: redux-form

我试着做的例子 https://redux-form.com/6.4.3/examples/asyncvalidation/

这是表单

的组件
    import React from "react";
import AddressForm from "./AddressForm";
import { Button } from "components/Button";
import { ContentLoader } from "components/utils";
import { Link } from "react-router-dom";
import { graphql, compose } from "react-apollo";
import { connect } from "react-redux";
import { reduxForm } from "redux-form";
import { success } from "react-notification-system-redux";
import { injectIntl } from "react-intl";
import addressesQuery from "./graphql/queries/address";
import updateOrCreateAddress from "./graphql/mutations/update-create";
import messages from "./messages";
import asyncValidate from "utilities/isValidEmail";

class AddressesForm extends React.Component {
  state = {
    saving: false
  };
  handleSubmit = ({ currentAddress, previousAddress }) => {
    const { intl: { formatMessage } } = this.props;
    const currentId = currentAddress.id;
    const previousId = previousAddress.id;
    const current = { ...currentAddress };
    const previous = { ...previousAddress };
    delete current.__typename;
    delete previous.__typename;
    delete current.id;
    delete previous.id;
    this.setState({ saving: true });
    const { data: { user: { tenant } } } = this.props;
    const tenantId = tenant.id;
    this.props
      .updateOrCreateAddress({
        variables: {
          update: {
            ...current,
            tenantCurrentAddressId: tenantId,
            id: currentId || 1
          },
          create: {
            ...current,
            tenantCurrentAddressId: tenantId
          }
        }
      })
      .then(() =>
        this.props.updateOrCreateAddress({
          variables: {
            update: {
              ...previous,
              tenantPreviousAddressId: tenantId,
              id: previousId || 1
            },
            create: {
              ...previous,
              tenantPreviousAddressId: tenantId
            }
          },
          refetchQueries: [{ query: addressesQuery }]
        })
      )
      .then(() => {
        this.props.onAfterSave();
        this.setState({ saving: false });
        this.props.dispatch(
          success({ message: formatMessage(messages["AddressesForm.saved"]) })
        );
        if (this.props.section === "application") this.props.onSubmit();
      });
  };

  render() {
    const {
      data: { loading, user },
      className,
      section,
      intl: { formatMessage }
    } = this.props;
    if (loading) return <ContentLoader />;

    const { tenant: { currentAddress = {}, previousAddress = {} } } = user;
    console.log(currentAddress);
    return (
      <form
        className={className}
        onSubmit={this.props.handleSubmit(this.handleSubmit)}
      >
        <div className="form-section-title-with-divider">
          <h5 className="form-section-title mb-0">
            {formatMessage(messages["AddressesForm.CurrentAddress"])}
          </h5>
        </div>
        <AddressForm data={currentAddress} namePrefix="currentAddress." />
        <div className="form-section-title-with-divider">
          <h5 className="form-section-title mb-0">
            {formatMessage(messages["AddressesForm.PreviousAddress"])}
          </h5>
        </div>
        <AddressForm data={previousAddress} namePrefix="previousAddress." />

        {section === "application" ? (
          <div className="wizard-form-footer">
            <div className="p-3 pl-5 pr-5">
              <div className="row row-item">
                <div className="col-md text-right">
                  <Link to="/" className="btn text-dark">
                    {formatMessage(messages["AddressesForm.Cancel"])}
                  </Link>
                  <Button
                    loading={this.state.saving}
                    buttonType="primary"
                    type="submit"
                  >
                    {formatMessage(messages["AddressesForm.Savecontinue"])}
                  </Button>
                </div>
              </div>
            </div>
          </div>
        ) : (
          <div className="row">
            <div className="col-md-4">
              <Button
                type="submit"
                buttonType="outline-primary"
                className="w-100"
                loading={this.state.saving}
              >
                {formatMessage(messages["AddressesForm.Save"])}
              </Button>
            </div>
          </div>
        )}
      </form>
    );
  }
}

export default compose(
  injectIntl,
  graphql(addressesQuery),
  graphql(updateOrCreateAddress, { name: "updateOrCreateAddress" }),
  connect((state, { data }) => {
    if (data.loading === false) {
      const currentAddress = data.user.tenant.currentAddress;
      console.log(currentAddress);

      return {
        initialValues: {
          currentAddress: {
            ...currentAddress,
            bondReturned: 2
          },
          previousAddress: data.user.tenant.previousAddress
        }
      };
    } else return {};
  }),
  reduxForm({
    form: "address-form",
    enableReinitialize: true,
    asyncValidate,
    asyncBlurFields: ["currentAddress.email", "previousAddress.email"]
  })
)(AddressesForm);

这是通过API验证电子邮件的功能

const isValidEmail = value => {
  const endpoint = process.env.REACT_APP_EMAIL_VALIDATION;
  const url = `${endpoint}&email=${value.currentAddressemail}`;
  return axios.get(url).then(result => {
    const isValid = result.data.format_valid;
    if (isValid === false) {
      const err = {};
      err["currentAddress.email"] = "That email is taken";
      throw { ...err };
    }
  });

但是如果isValid = false asyncValidate没有传递错误 但是,如果我namePrefix="currentAddress.更改namePrefix="currentAddress_err["currentAddress.email"] = "That email is taken";改变err["currentAddress_email"] = "That email is taken";它是有效的 如果namePrefix被点分隔,则无效

为什么asyncValidate没有以Redux格式传递错误?

如果用点

分开,

来自网站的示例也无效

import React from 'react'
import { Field, reduxForm } from 'redux-form'
import validate from './validate'
import asyncValidate from './asyncValidate'

const renderField = ({
  input,
  label,
  type,
  meta: { asyncValidating, touched, error }
}) => {
  console.log(asyncValidating)
  return (
    <div>
      <label>{label}</label>
      <div className={asyncValidating ? 'async-validating' : ''}>
        <input {...input} type={type} placeholder={label} />
        {touched && error && <span>{error}</span>}
      </div>
    </div>
  )
}

const AsyncValidationForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field
        name="username.name"
        type="text"
        component={renderField}
        label="Username"
      />
      <Field
        name="password"
        type="password"
        component={renderField}
        label="Password"
      />
      <div>
        <button type="submit" disabled={submitting}>
          Sign Up
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'asyncValidation', // a unique identifier for this form
  validate,
  asyncValidate,
  asyncBlurFields: ['username.name']
})(AsyncValidationForm)

asyncValidate

import axios from 'axios'
//const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const asyncValidate = (values /*, dispatch */) => {
  console.log(values)
  return axios
    .get(
      `http://apilayer.net/api/check?access_key=60965168513fee8c9ee79cdd33b8fe20&email=${
        values.username
      }`
    )
    .then(result => {
      const isValid = result.data.format_valid
      console.log(isValid)
      if (!isValid) {
        console.log({ 'username.name': 'That username is taken' })
        throw { 'username.name': 'That username is taken' }
      }
    })
}

export default asyncValidate

0 个答案:

没有答案