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
相关产品推荐
相关产品推荐

