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

React输入框失焦状态管理:点击模态框输入保留?符号

React输入框与模态框交互逻辑优化

问题场景

现有React代码如下:

import { useEffect, useState } from "react";
import "./styles.css";

const inputDefautValues = ["first val", "second value"];

const Input = ({ setIsopen, val }) => {
  const [value, setValue] = useState("");

  useEffect(() => {
    setValue(val);
  }, [val]);
  return (
    <input
      value={value}
      onChange={(e) => {
        setIsopen(e.target.value === "?");
        setValue(e.target.value);
      }}
      onBlur={(e) => e.target.value === "?" && setValue(val)}
    />
  );
};

const Modal = ({ data }) => {
  return (
    <div>
      Modal data: <input />
    </div>
  );
};

export default function App() {
  const [isOpen, setIsopen] = useState(false);
  return (
    <div className="App">
      {inputDefautValues.map((val, i) => (
        <Input val={val} key={i} setIsopen={setIsopen} />
      ))}
      {isOpen && <Modal />}
    </div>
  );
}

当前问题

输入框输入?后:

  • 点击其他输入框时,原输入框恢复初始值,符合预期;
  • 点击模态框内的输入框时,原输入框也会恢复初始值,不符合需求。

期望行为

输入?后:

  • 点击其他输入框,原输入框恢复初始值;
  • 点击模态框内的输入框,原输入框保留?。

解决方案

核心思路是通过onBlur事件的relatedTarget属性,判断焦点是否转移到模态框内的元素,以此决定是否恢复输入框初始值。

修改后的完整代码

import { useEffect, useState } from "react";
import "./styles.css";

const inputDefautValues = ["first val", "second value"];

const Input = ({ setIsopen, val }) => {
  const [value, setValue] = useState("");

  useEffect(() => {
    setValue(val);
  }, [val]);

  const handleBlur = (e) => {
    // 判断新焦点是否在模态框容器内
    const isFocusInModal = e.relatedTarget?.closest('.modal-container') !== null;
    // 仅当值为?且焦点不在模态框内时,恢复初始值
    if (e.target.value === "?" && !isFocusInModal) {
      setValue(val);
    }
  };

  return (
    <input
      value={value}
      onChange={(e) => {
        setIsopen(e.target.value === "?");
        setValue(e.target.value);
      }}
      onBlur={handleBlur}
    />
  );
};

const Modal = ({ data }) => {
  // 给模态框外层容器添加标识类名
  return (
    <div className="modal-container">
      Modal data: <input />
    </div>
  );
};

export default function App() {
  const [isOpen, setIsopen] = useState(false);
  return (
    <div className="App">
      {inputDefautValues.map((val, i) => (
        <Input val={val} key={i} setIsopen={setIsopen} />
      ))}
      {isOpen && <Modal />}
    </div>
  );
}

关键改动说明

  1. 模态框容器添加类名:为Modal组件的外层div添加modal-container类,作为识别模态框元素的标识。
  2. 优化失焦逻辑:在Input组件的handleBlur函数中,通过e.relatedTarget获取失焦后获得焦点的元素,使用closest('.modal-container')判断该元素是否属于模态框。只有当焦点不在模态框内且输入值为?时,才触发初始值恢复操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:00:41