React- 如何将 React 图标添加到根据 Formik / Yup 验证而变化的输入字段?

React- How do I add react icons to input field that change depending on Formik / Yup validation?

我是 React 的新手,我正在尝试根据 Formik / Yup 验证让特定图标显示在输入字段的末尾。 因此,如果我的验证失败,我希望在字段末尾显示一个红叉图标,如果验证成功则显示一个勾号图标。图标应该只在验证开始后显示。

与此图片类似的内容。

这是我当前的登录表单组件:

import React from "react";
import { Formik, Form, Field } from "formik";
import * as Yup from "yup";

const LoginForm = () => (
  <Formik
    initialValues={{ email: "", password: "" }}
    onSubmit={(values) => {
      console.log(values);
    }}
    validationSchema={Yup.object().shape({
      email: Yup.string().email().required(),
      password: Yup.string().required(),
    })}
  >
    {(props) => {
      const { errors, touched, isSubmitting } = props;
      return (
        <Form >
          <label htmlFor="email"></label>
          <Field
            type="text"
            name="email"
            placeholder="Email address"
            className={errors.email && touched.email && "errors"}
          />
          {errors.email && touched.email && (
            <div className="errorFeedback">The email is incorrect.</div>
          )}
          <Field
            type="password"
            name="password"
            placeholder="Password"
            className={errors.password && touched.password && "errors"}
          />
          {errors.password && touched.password && (
            <div className="errorFeedback">The password is incorrect.</div>
          )}
          <button type="submit" >
            Sign In
           </button>
        </Form>
      );
    }}
  </Formik>
);

我认为它必须与 material UI 文本字段和 Inputprops 相关才能实现。

所以我用 Material UI 库解决了这个问题。我的脚步

  1. 我将我的 Formik {Field} 模块制作成 Material UI {Textfield} 模块,以便能够使用 InputProps={} 添加图标。这还需要读取 {handleChange, handleBlur} 道具,否则验证不会在字段中启动。
  2. 我使用 endAdorment 属性 将图标添加到字段中,并直接在其中添加条件以根据 Formik 验证显示正确的图标。

我的代码在所有更改之后,我还没有使用 API 调用验证来检查它,但我认为它与它的工作方式类似。

import React from "react";
import { Formik, Form, Field } from "formik";
import * as Yup from "yup";
import { TextField, InputAdornment } from "@material-ui/core";
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
import CancelIcon from "@material-ui/icons/Cancel";

const LoginForm = () => (
  <Formik
    initialValues={{ email: "", password: "" }}
    onSubmit={(values) => {
      console.log(values);
    }}
    validationSchema={Yup.object().shape({
      email: Yup.string().email().required(),
      password: Yup.string().required().min(8),
    })}
  >
    {(props) => {
      const { errors, touched, handleChange, handleBlur } = props;
      return (
        <Form >
          <Field
            variant="outlined"
            component={TextField}
            type="text"
            name="email"
            onChange={handleChange}
            onBlur={handleBlur}
            id="email"
            placeholder="Email address"
            size="small"
            error={errors.email && touched.email && true}
            // Mui icons based on Validation
            InputProps={{
              endAdornment: (
                <InputAdornment position="end" style={{ outline: "none" }}>
                  {errors.email && touched.email && (
                    <CancelIcon
                      style={{ color: "red" }}
                      fontSize="default"
                    ></CancelIcon>
                  )}
                  {!errors.email && touched.email && (
                    <CheckCircleIcon
                      style={{ color: "#05cc30" }}
                      fontSize="default"
                    ></CheckCircleIcon>
                  )}
                </InputAdornment>
              ),
            }}
          />
          <Field
            variant="outlined"
            component={TextField}
            onChange={handleChange}
            onBlur={handleBlur}
            type="password"
            id="password"
            placeholder="Password"
            size="small"
            error={errors.password && touched.password && true}
            // Mui icons based on Validation
            InputProps={{
              endAdornment: (
                <InputAdornment position="end" style={{ outline: "none" }}>
                  {errors.password && touched.password && (
                    <CancelIcon
                      style={{ color: "red" }}
                      fontSize="default"
                    ></CancelIcon>
                  )}
                  {!errors.password && touched.password && (
                    <CheckCircleIcon
                      style={{ color: "#05cc30" }}
                      fontSize="default"
                    ></CheckCircleIcon>
                  )}
                </InputAdornment>
              ),
            }}
          />
          // Add your button
        </Form>
      );
    }}
  </Formik>
);

由于我找不到这个确切问题的直接答案,并且 9 个月前提出的关于这个确切问题的类似问题也没有得到回答,我发布了一个我实施的简单解决方案。希望对您有所帮助。