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

React中Reshaped UI输入框触发e.target is undefined错误求助

解决Reshaped UI TextField的e.target is undefined错误

问题描述

我是React新手,正在学习使用Firebase实现用户认证功能,当前使用Reshaped UI库开发登录页面。在输入框中输入内容时,控制台提示e.target is undefined错误,以下是我的登录页代码:

import {
  Button,
  Reshaped,
  View,
  useTheme,
  Frame,
  Text,
  Container,
  FormControl,
  TextField,
  Checkbox,
  Divider,
} from "reshaped";
import "reshaped/themes/reshaped/theme.css";
import { Link, useNavigate } from "react-router-dom";
import { FcGoogle } from "react-icons/fc";
import { useState } from "react";
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
import toast, { Toaster } from "react-hot-toast";

function SignIn() {
  return (
    <Reshaped theme="reshaped">
      <Frame>
        <SignPanel />
      </Frame>
    </Reshaped>
  );
}

let test;

const SignPanel = () => {
  const { setColorMode } = useTheme();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const navigate = useNavigate();
  const notify = () => toast.error("Try again later.");

  const handleSubmit = async (event) => {
    event.preventDefault();

    try {
      await firebase.auth().signInWithEmailAndPassword(email, password);
      console.log("User signed in successfully");
    } catch (error) {
      notify();
    }
  };

  let dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
  if (dark) {
    setColorMode("dark");
  } else {
    setColorMode("light");
  }
  return (
    <Reshaped theme="reshaped">
      <Toaster />
      <View position="absolute" insetTop={4} insetEnd={4} zIndex={1000}>
        <Link to="/sign-up" style={{ textDecoration: "none" }}>
          <Button rounded variant="outline">
            Sign up
          </Button>
        </Link>
      </View>
      <Frame height="100vh" justify="center">
        <Container width="400px">
          <center>
            <Text variant="title-1">Sign in</Text>
            <View height={2} />
            <Text>
              Welcome back! If you've got an account with us, please sign in
              below.
            </Text>
          </center>
          <View height={3} />
          <FormControl onSubmit={handleSubmit}>
            <FormControl.Label>Email</FormControl.Label>
            <TextField
              name="email"
              placeholder="Enter your email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
            <View height={2} />
            <FormControl.Label>Password</FormControl.Label>
            <TextField
              name="password"
              placeholder="Enter your password"
              inputAttributes={{ type: "password" }}
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
            />
            <View height={5} />
            <Checkbox
              name="keepSigned"
              defaultChecked={false}
              disabled={false}
              hasError={false}
              indeterminate={false}
            >
              Keep me signed in
            </Checkbox>
            <View height={5} />
            <Button fullWidth color="primary" loading={test} type="submit">
              Sign in
            </Button>
            <View height={3} />
            <center>
              <Link to="/forgot">Forgot password?</Link>
            </center>
          </FormControl>
          <View height={4} />
          <Divider />
          <View height={4} />
          <Button
            variant="outline"
            fullWidth
            startIcon={FcGoogle}
            loading={test}
          >
            Sign in with Google
          </Button>
        </Container>
      </Frame>
    </Reshaped>
  );
};

export default SignIn;

解决方案

1. 修复TextField的onChange回调

Reshaped UI的TextField组件和原生input不同,它的onChange回调直接传递输入框的当前值,而非原生的事件对象。你之前的代码试图访问e.target,但这里的参数e实际上就是输入值,所以会导致e.target is undefined错误。

修改两个TextField的onChange逻辑:

// Email输入框
<TextField
  name="email"
  placeholder="Enter your email"
  required
  value={email}
  onChange={(value) => setEmail(value)} // 直接用value参数
/>

// Password输入框
<TextField
  name="password"
  placeholder="Enter your password"
  inputAttributes={{ type: "password" }}
  value={password}
  onChange={(value) => setPassword(value)} // 直接用value参数
  required
/>

2. 修复主题切换的副作用

你当前直接在组件渲染流程中调用setColorMode,这会导致每次组件渲染时都执行该逻辑,可能引发不必要的重渲染。应该用useEffect包裹,只在组件挂载或系统主题变化时执行:

import { useEffect } from "react"; // 先导入useEffect

const SignPanel = () => {
  const { setColorMode } = useTheme();
  // ...其他状态和函数

  useEffect(() => {
    const updateColorMode = () => {
      const dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
      setColorMode(dark ? "dark" : "light");
    };
    // 初始化执行一次
    updateColorMode();
    // 监听系统主题变化
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    mediaQuery.addEventListener("change", updateColorMode);
    // 清理监听
    return () => mediaQuery.removeEventListener("change", updateColorMode);
  }, [setColorMode]);

  // ...剩余代码
};

3. 其他优化点

  • 变量test未定义,建议移除或赋值(比如设为const test = false;),避免loading={test}传递undefined。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:03:00