React 输入中的 Onchange 导致输入在每个字母上重新呈现
Posted
技术标签:
【中文标题】React 输入中的 Onchange 导致输入在每个字母上重新呈现【英文标题】:Onchange in React input causes the input to rerender on every letter 【发布时间】:2021-12-03 22:21:48 【问题描述】:所以我在两个函数中创建了输入,并在Onchange
上获取了输入到它们中的值。但是每当我输入输入时,我一次只能输入一个字母,然后才会失去焦点,我相信这是因为组件一直在渲染。
我还意识到,每当我删除 Onchange 和 value 道具时,一切都会恢复正常,我可以轻松地输入所有内容。我该如何解决这个问题?
App.js
import style from "./auth.module.css";
import useEffect, useRef, useState from "react";
import useAuthState from 'react-firebase-hooks/auth';
import auth, signInWithEmailAndPassword, signInWithGoogle, registerWithEmailAndPassword from "../../firebase";
import CSSTransition from "react-transition-group";
function Auth()
const [activeMenu, setActiveMenu] = useState("main");
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, loading, error] = useAuthState(auth);
const Emailform = () =>
return (
<div className=style.formBox>
<label className=style.label>Email:</label>
<form className=style.input>
<input
type="email"
name="email"
required="true"
value=email
onChange=(e) => setEmail(e.target.value) />
</form>
</div>
);
const Passform = () =>
return (
<div className=style.formBox>
<label className=style.label>Password:</label>
<form className=style.input>
<input
type="password"
name="password"
required="true"
value=password
onChange=(e) => setPassword(e.target.value) />
</form>
</div>
);
let domNode = useClickOutside(() =>
setActiveMenu(false);
);
return (
<div className=style.container>
<Login />
<Signup />
</div>
);
function AuthType(props)
return (
<a
href=props.link
className=style.menuItem
onClick=() => props.goToMenu && setActiveMenu(props.goToMenu)
>
props.children
</a>
);
/* Login */
function Login()
return (
<CSSTransition in=activeMenu === "main" unmountOnExit timeout=500>
<div ref=domNode>
<div className=style.login>
<h1 className=style.title>Clip It</h1>
/* Email and Password */
<Emailform/>
<Passform/>
<div className=style.button>
<input
type="submit"
value="Login"
onClick=() => signInWithEmailAndPassword(email, password) />
<input
type="submit"
value="Login with Google"
onClick=signInWithGoogle />
</div>
<div className=style.text>
<p className=style.plink>Forgot Password</p>
<div>
Need an account?
<AuthType goToMenu="Signup">click here</AuthType>
</div>
</div>
</div>
</div>
</CSSTransition>
);
function Signup()
return (
<CSSTransition in=activeMenu === "Signup" unmountOnExit timeout=500>
<div ref=domNode>
<div className=style.signUp>
<div className=style.title> Clip It</div>
<Form label="First Name" type="text" />
<Form label="Last Name" type="Text" />
<Form label="Email" type="email"/>
<Form label="Date of Birth" type="date" />
<Form label="Password" type="password"/>
<Form label="Confirm Password" type="password" />
<div className=style.button>
<input type="submit" value="Sign Up" />
</div>
<div className=style.text>
have an
<AuthType goToMenu="main"> account</AuthType>
</div>
</div>
</div>
</CSSTransition>
);
let useClickOutside = (handler) =>
let domNode = useRef();
useEffect(() =>
let clickListener = (event) =>
if (domNode.current && !domNode.current.contains(event.target))
handler();
;
document.addEventListener("mousedown", clickListener);
return () =>
document.removeEventListener("mousedown", clickListener);
;
);
return domNode;
;
function Form(props)
return (
<div className=style.formBox>
<label className=style.label>props.label:</label>
<form className=style.input>
<input
type=props.input
name=props.input
required="true" />
</form>
</div>
);
export default Auth;
【问题讨论】:
【参考方案1】:可能重复:In React ES6, why does the input field lose focus after typing a character?
一种解决方案是将电子邮件表单移到父组件之外。
const Emailform = ( onChange ) =>
return (
<div>
<label>Email:</label>
<form>
<input
type="email"
name="email"
required="true"
onChange=onChange
/>
</form>
</div>
);
;
const App = () =>
const [email, setEmail] = useState("");
return (
<div>
<Emailform onChange=(e) => setEmail(e.target.value) />
</div>
);
;
【讨论】:
仍然没有变化...而且更糟糕的是,我现在无法输入任何内容... 在不将电子邮件/值传递给 Emailform 的情况下试一试。我已将其从示例中删除。 这也不行……【参考方案2】:不要将您的组件定义放在其他组件中。如果这样做,您会在每次渲染时创建一个新组件。
您需要设法将 Emailform、Passform 移到 Auth 之外。
结帐this sandbox 进行实验
function Auth()
// ? the bad place to define components
const Emailform = () =>
...
// ? the bad place to define components
const Passform = () =>
...
【讨论】:
以上是关于React 输入中的 Onchange 导致输入在每个字母上重新呈现的主要内容,如果未能解决你的问题,请参考以下文章
react input 输入中文拼音和onChange事件的交互
React 输入设置状态 onChange 设置多个状态属性
具有数百个输入的巨大 React 状态数组,状态变化缓慢 onChange