React setState hook 不断重置和渲染页面两次
React setState hook keeps resetting and rendering the page twice
我有一个 React 应用程序 Form
组件分为 Login
和 Signup
形式。它应该默认呈现 Signup
但如果单击登录按钮则切换到 Login
。单击 login
按钮时,页面会非常短暂地切换到 Login
表单,然后再切换回 Signup
表单。我不知道是什么原因造成的。我尝试将 const [page, setPage] = setState("signup")
放在父级 App
中,并将 setPage
作为道具与 page
一起传递。这产生了相同的结果。我认为此问题与 this one 类似,但尚未解决。
这是应用程序:
import Form from "./components/Signup-Form.js";
function App() {
return (
<div className="App">
<h1>Welcome</h1>
<Form />
</div>
);
}
export default App;
和Signup-Form.js
:
import React from "react";
import { useState, useEffect } from "react";
import "./Forms.css";
import { InputField, Buttons } from "./Inputs";
function Form() {
const [page, setPage] = useState("signup");
const pageLabel = page;
let Signup = () => {
function toLogin() {
setPage("login");
}
return (
<form action="" method="get" className="form">
<div className="input-container">
<InputField name="Company Name" id="comp-name" type="text" />
<InputField name="Company ID" id="comp-id" type="text" />
<InputField name="Username" id="username" type="text" />
<InputField name="Email" id="email" type="email" />
<InputField name="Password" id="password" type="password" />
<InputField name="Confirm Password" id="confirm-password" type="password" />
</div>
<div className="btns">
<Buttons name="Sign Up" id="signup-btn" type="submit" cls="success" />
<Buttons name="Log In" id="login-btn" type="button" cls="success" alt="true" onClick={toLogin} />
</div>
</form>
);
};
let Login = () => {
function toSignup() {
setPage("signup");
}
return (
<form action="" method="get" className="form">
<div className="input-container">
<InputField name="Company ID" id="comp-id" type="text" />
<InputField name="Password" id="password" type="password" />
</div>
<div className="btns">
<Buttons name="Log In" id="login-btn" type="submit" cls="success" />
<Buttons name="Sign Up" id="signup-btn" type="submit" cls="success" alt onClick={toSignup} />
</div>
</form>
);
};
let form = (formType) => (
<div className="outer-wrapper">
<div className="form-wrapper">
<label className="form-title">{pageLabel}</label>
{formType}
</div>
</div>
);
if (page === "signup") {
const signup = Signup();
return form(signup);
} else if (page === "login") {
const login = Login();
return form(login);
}
}
export default Form;
在您单击“登录”按钮并获得“登录”页面并且页面立即重新呈现并获得“注册”页面后,原因是您的示例中有条件呈现。单击“登录”按钮后,您的状态仍然是以前的状态,因此单击后您将进入主(注册)页面。
建议将结构渲染改成这样:
...
return (
<div className="outer-wrapper">
<div className="form-wrapper">
<label className="form-title">{pageLabel}</label>
{page === "signup" && Signup()}
{page === "login" && Login()}
</div>
</div>
);
这是动作中的示例 - https://codesandbox.io/s/smoosh-water-6jj18?file=/src/App.js
我有一个 React 应用程序 Form
组件分为 Login
和 Signup
形式。它应该默认呈现 Signup
但如果单击登录按钮则切换到 Login
。单击 login
按钮时,页面会非常短暂地切换到 Login
表单,然后再切换回 Signup
表单。我不知道是什么原因造成的。我尝试将 const [page, setPage] = setState("signup")
放在父级 App
中,并将 setPage
作为道具与 page
一起传递。这产生了相同的结果。我认为此问题与 this one 类似,但尚未解决。
这是应用程序:
import Form from "./components/Signup-Form.js";
function App() {
return (
<div className="App">
<h1>Welcome</h1>
<Form />
</div>
);
}
export default App;
和Signup-Form.js
:
import React from "react";
import { useState, useEffect } from "react";
import "./Forms.css";
import { InputField, Buttons } from "./Inputs";
function Form() {
const [page, setPage] = useState("signup");
const pageLabel = page;
let Signup = () => {
function toLogin() {
setPage("login");
}
return (
<form action="" method="get" className="form">
<div className="input-container">
<InputField name="Company Name" id="comp-name" type="text" />
<InputField name="Company ID" id="comp-id" type="text" />
<InputField name="Username" id="username" type="text" />
<InputField name="Email" id="email" type="email" />
<InputField name="Password" id="password" type="password" />
<InputField name="Confirm Password" id="confirm-password" type="password" />
</div>
<div className="btns">
<Buttons name="Sign Up" id="signup-btn" type="submit" cls="success" />
<Buttons name="Log In" id="login-btn" type="button" cls="success" alt="true" onClick={toLogin} />
</div>
</form>
);
};
let Login = () => {
function toSignup() {
setPage("signup");
}
return (
<form action="" method="get" className="form">
<div className="input-container">
<InputField name="Company ID" id="comp-id" type="text" />
<InputField name="Password" id="password" type="password" />
</div>
<div className="btns">
<Buttons name="Log In" id="login-btn" type="submit" cls="success" />
<Buttons name="Sign Up" id="signup-btn" type="submit" cls="success" alt onClick={toSignup} />
</div>
</form>
);
};
let form = (formType) => (
<div className="outer-wrapper">
<div className="form-wrapper">
<label className="form-title">{pageLabel}</label>
{formType}
</div>
</div>
);
if (page === "signup") {
const signup = Signup();
return form(signup);
} else if (page === "login") {
const login = Login();
return form(login);
}
}
export default Form;
在您单击“登录”按钮并获得“登录”页面并且页面立即重新呈现并获得“注册”页面后,原因是您的示例中有条件呈现。单击“登录”按钮后,您的状态仍然是以前的状态,因此单击后您将进入主(注册)页面。
建议将结构渲染改成这样:
...
return (
<div className="outer-wrapper">
<div className="form-wrapper">
<label className="form-title">{pageLabel}</label>
{page === "signup" && Signup()}
{page === "login" && Login()}
</div>
</div>
);
这是动作中的示例 - https://codesandbox.io/s/smoosh-water-6jj18?file=/src/App.js