You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Formik实现点击输入框时渲染元素的方法

在Formik中实现输入框点击显示/外部点击隐藏元素的效果

嘿,我懂你想要的效果——点击输入框时渲染一个额外元素,点击页面其他区域就让它消失,就像一个切换器对吧?其实在Formik里实现这个和普通React组件的思路大同小异,只是要把状态管理和Formik的表单逻辑结合起来就行。我来帮你修改代码实现这个功能:

首先,我们需要在组件内部用useState来控制元素的显示状态,再通过useEffect添加全局点击监听来处理外部点击隐藏的逻辑。下面是完整的修改后的代码:

import React, { useState, useEffect, useRef } from "react";
import { Formik } from "formik";
import * as EmailValidator from "email-validator";
import * as Yup from "yup";

const ValidatedLoginForm = () => {
  // 管理元素显示状态
  const [showElement, setShowElement] = useState(false);
  // 创建输入框的ref,用来判断点击是否在输入框内
  const emailInputRef = useRef(null);
  // 创建要显示元素的ref,判断点击是否在元素内
  const dropdownRef = useRef(null);

  useEffect(() => {
    // 处理外部点击的函数
    const handleClickOutside = (event) => {
      if (
        emailInputRef.current &&
        !emailInputRef.current.contains(event.target) &&
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target)
      ) {
        setShowElement(false);
      }
    };

    // 添加全局点击监听
    document.addEventListener("mousedown", handleClickOutside);
    // 组件卸载时移除监听,避免内存泄漏
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  return (
    <Formik
      initialValues={{ email: "", password: "" }}
      onSubmit={(values, { setSubmitting }) => {
        console.log(values);
        console.log("hello there ");
        setSubmitting(false);
      }}
      validationSchema={Yup.object().shape({
        email: Yup.string().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.")
      })}
    >
      {(props) => {
        const {
          values,
          touched,
          errors,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit
        } = props;

        return (
          <div className="container">
            <div className="row">
              <form onSubmit={handleSubmit}>
                <br />
                <input
                  ref={emailInputRef}
                  name="email"
                  type="text"
                  placeholder="Enter your email"
                  value={values.email}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  // 点击输入框时显示元素
                  onFocus={() => setShowElement(true)}
                  className={errors.email && touched.email && "error"}
                />
                {/* 根据状态渲染额外元素 */}
                {showElement && (
                  <div ref={dropdownRef} className="your-element-class">
                    这是点击输入框后显示的元素!
                  </div>
                )}
                <br />
                <br />
                {errors.email && touched.email && (
                  <div className="input-feedback">{errors.email}</div>
                )}
                <br />
                <input
                  name="password"
                  type="password"
                  placeholder="Enter your password"
                  value={values.password}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  className={errors.password && touched.password && "error"}
                />
                <br />
                <br />
                {errors.password && touched.password && (
                  <div className="input-feedback">{errors.password}</div>
                )}
                <button type="submit" disabled={isSubmitting}>
                  Login
                </button>
              </form>
            </div>
            <div className="row">
              <button className="btn btn-default">Value</button>
            </div>
          </div>
        );
      }}
    </Formik>
  );
};

export default ValidatedLoginForm;

关键步骤说明:

  • 状态管理:用useState创建showElement变量来控制元素的显示/隐藏;
  • Ref引用:给输入框和要显示的元素添加ref,用来判断点击事件的目标是否在这两个元素内部;
  • 全局点击监听:通过useEffect添加mousedown事件监听,当点击的目标不在输入框和显示元素内时,就把showElement设为false;
  • 输入框聚焦事件:给邮箱输入框添加onFocus事件,触发时把showElement设为true,显示目标元素。

这样就能实现你想要的点击输入框显示元素、点击外部隐藏的效果啦,而且完全兼容Formik的表单逻辑~

内容的提问来源于stack exchange,提问作者saurabh kapoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:47:58