首页 > 解决方案 > 使用 Formik 的服务器端验证错误

问题描述

我正在注册。我必须查询数据库以检查唯一的电子邮件。使用 Formik 时如何实现相同的服务器端验证错误?

起初我在做服务器端验证:

import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Card from "react-bootstrap/Card";
import Alert from "react-bootstrap/Alert";

class Signup extends Component {
  constructor() {
    super();
    this.state = {
      name: "",
      email: "",
      password: "",
      error: "",
      welcomeMessage: false,
    };

    this.handleChange = (name) => (e) => {
      this.setState({ error: "" }); // we clear the old error while handling the change
      this.setState({ [name]: e.target.value });
    };

    this.clickSubmit = (e) => {
      e.preventDefault();
      const { name, email, password } = this.state;
      const user = {
        name,
        email,
        password,
      };

      this.signup(user).then((data) => {
        if (data.error) {
          this.setState({ error: data.error });
        } else {
          this.setState({
            error: "",
            name: "",
            email: "",
            password: "",
            welcomeMessage: true
          });
        }
      });
    };
  }

  signup = (user) => {
    return fetch("http://localhost:4000/api/signup", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify(user),
    })
      .then((res) => {
        return res.json();
      })
      .catch((err) => console.log(err));
  };

  render() {
    const { name, email, password, error, welcomeMessage } = this.state;
    return (
      <Card body>
        <Alert variant="danger" style={{ display: error ? "block" : "none" }}>
          {error}
        </Alert>
        <Alert
          variant="success"
          style={{ display: welcomeMessage ? "block" : "none" }}
        >
          Signup Success! Please login
        </Alert>
        <Form onSubmit={this.clickSubmit}>
          <Form.Group controlId="Name">
            <Form.Label>Name</Form.Label>
            <Form.Control
              type="text"
              onChange={this.handleChange("name")}
              value={name}
              placeholder="Name"
            />
          </Form.Group>
          <Form.Group controlId="Email">
            <Form.Label>Email address</Form.Label>
            <Form.Control
              type="email"
              onChange={this.handleChange("email")}
              value={email}
              placeholder="Enter email"
            />
            <Form.Text className="text-muted">
              We'll never share your email with anyone else.
            </Form.Text>
          </Form.Group>

          <Form.Group controlId="Password">
            <Form.Label>Password</Form.Label>
            <Form.Control
              type="password"
              onChange={this.handleChange("password")}
              value={password}
              placeholder="Password"
            />
          </Form.Group>

          <Button variant="dark" type="submit">
            Submit
          </Button>
        </Form>
      </Card>
    );
  }
}

export default Signup;



=======================================================
**The code using formik**

import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Card from "react-bootstrap/Card";
import Alert from "react-bootstrap/Alert";
import FormControl from "react-bootstrap/FormControl";
import { Formik } from "formik";
import * as Yup from "yup";

class Signin extends Component {
  render() {
    return (
      <Formik
        initialValues={{
          email: "",
          password: "",
        }}
        validationSchema={Yup.object().shape({
          email: Yup.string().email("Invalid Email").required("Required"),
          password: Yup.string()
            .required("No password provided.")
            .min(8, "Password is too short - should be 8 chars minimum.")
            .matches(/(?=.*[0-9])/, "Password must contain a number."),
        })}
        onSubmit={(values, actions) => {

          this.signin(values).then((data) => {
            if (data.error) {
              this.setState({ error: data.error });
            } else {
              this.setState({
                //   authenticate
                // redirect
                welcomeMessage: true,
              });
            }
          });
        }}
      >
        {(props) => (
          <Form noValidate onSubmit={props.handleSubmit}>
            <Form.Group controlId="Email">
              <Form.Label>Email address</Form.Label>
              <Form.Control
                type="email"
                onChange={props.handleChange}
                onBlur={props.handleBlur}
                value={props.values.email}
                name="email"
                placeholder="Enter email"
                isValid={props.touched.email && !props.errors.email}
                isInvalid={props.touched.email && props.errors.email}
              />
              <Form.Control.Feedback type="invalid">
                {props.errors.email}
              </Form.Control.Feedback>
              <Form.Control.Feedback type="valid">
                Good job
              </Form.Control.Feedback>
            </Form.Group>

            <Form.Group controlId="Password">
              <Form.Label>Password</Form.Label>
              <Form.Control
                type="password"
                onChange={props.handleChange}
                onBlur={props.handleBlur}
                value={props.values.password}
                placeholder="Password"
                name="password"
                isValid={props.touched.password && !props.errors.password}
                isInvalid={props.touched.password && props.errors.password}
              />
              <Form.Control.Feedback type="invalid">
                {props.errors.password}
              </Form.Control.Feedback>
            </Form.Group>

            <Button variant="primary" type="submit">
              Submit
            </Button>
          </Form>
        )}
      </Formik>
    );
  }

  signin = (values) => {
    return fetch("http://localhost:4000/api/signin", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify(values),
    })
      .then((res) => {
        return res.json();
      })
      .catch((err) => console.log(err));
  };
}

export default Signin;

标签: javascriptnode.jsreactjsformik

解决方案


推荐阅读