[英]How to update multiple elements conditionally at once
我是 React 的新手,并试图找出最好的方法是一次更新多个元素,而不必一直重复代码。
我有一个登录页面,它有几个状态:“LOGIN”、“SIGNUP”或“FORGOT_PASSWORD”。 根据当前模式,我已经能够使用 renderForm() 更改使用的表单。 但是,我还需要更新根组件中的其他一些文本,但不知道最有效的方法是什么。 当然,我可以为我必须更改的每个文本片段重复 renderForm() ,但这似乎不是很干燥。
这是我的(非常简化的)代码:
function Login() {
const [mode, setMode] = useState("LOGIN");
function renderForm(): ReactElement {
return (
<>
{
{
LOGIN: <EmailPasswordForm setMode={setMode} type="login"/>,
SIGNUP: <EmailPasswordForm setMode={setMode} type="signup"/>,
FORGOT_PASSWORD: <ForgotPassword setMode={setMode} auth={auth} />,
}[mode]
}
</>
);
}
return (
<div>
<h2>
Sign in to your account //title that needs to change depending on the mode
</h2>
{renderForm()}
<a href="/privacy">Privacy Info</a>
<p>
Some text that also needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
</p>
<OAuthSignUpComponents/>
<p>
Some more text that needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
</p>
</div>
)
}
function EmailPasswordForm({setMode, type}) {
const handleSubmit = () => {
type == "login" ? loginLogic() : signupLogic();
}
return(
<form>
<input type="email/>
<input type="password"/>
<button type="button" onClick={handleSubmit}>
{ type == "login" ? <button onClick={setMode("SIGNUP")>Sign up instead</button> : <button onClick={setMode("LOGIN")>Sign in instead</button> }
</form>
)
}
function ForgotPasswordForm({setMode}) {
return(
<form>
<input type="email/>
<button type="button">
</form>
)
}
我尝试过的一件事是在 renderForm() 中使用一个开关,如下所示:
const [title, setTitle] = useState("Sign in to your account");
function renderForm(){
switch(mode) {
case "LOGIN":
setTitle("Sign in to your account")
return <EmailPasswordForm setMode={setMode} type="login"/>;
case "SIGNUP":
setTitle("Sign in to your account")
return <EmailPasswordForm setMode={setMode} type="signup"/>;
case "FORGOT_PASSWORD":
setTitle("Reset Password")
return <ForgotPasswordForm setMode={setMode}/>
}
}
但这也不起作用,因为它会导致太多的重新渲染错误。
您应该在效果中使用 setTitle 以便不再出现渲染问题,因为您的主渲染 function 中不应有副作用,仅在回调和效果中。 您绝对可以将渲染表单保留为 object 而不是开关盒。 无论哪种方式都行得通。
useEffect(() => {
switch(mode) {
case "LOGIN":
setTitle("Sign in to your account")
case "SIGNUP":
setTitle("Sign in to your account")
case "FORGOT_PASSWORD":
setTitle("Reset Password")
}
return () => {
// You can then set the original title of the application to clean up once they've logged in.
// setTitle('Original Title')
}
}, [mode])
function renderForm(){
switch(mode) {
case "LOGIN":
return <EmailPasswordForm setMode={setMode} type="login"/>;
case "SIGNUP":
return <EmailPasswordForm setMode={setMode} type="signup"/>;
case "FORGOT_PASSWORD":
return <ForgotPasswordForm setMode={setMode}/>
}
}
您甚至不必将开关盒或 object 放在内部 function 中。
const formMap={
LOGIN: <EmailPasswordForm setMode={setMode} type="login"/>,
SIGNUP: <EmailPasswordForm setMode={setMode} type="signup"/>,
FORGOT_PASSWORD: <ForgotPassword setMode={setMode} auth={auth} />,
};
return(<div>
<h2>
Sign in to your account //title that needs to change depending on the mode
</h2>
{formMap[mode]}
<a href="/privacy">Privacy Info</a>
<p>
Some text that also needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
</p>
<OAuthSignUpComponents/>
<p>
Some more text that needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
</p>
</div>)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.