英文:
React: How to use conditional render and react-hooks to update another component's state?
问题
Login.jsx
import React from "react";
import Input from "./Input";
function Login() {
return (
<div className="loginContainer">
<div className="loginChildContainer">
<h1>Welcome Back!</h1>
<p>Lorem lorem lorem lorem lorem</p>
<Input type="text" placeholder="Username" />
<Input type="password" placeholder="Password" />
<button type="submit">Sign In</button>
</div>
</div>
);
}
export default Login;
Register.jsx
import React from "react";
import Input from "./Input";
import FacebookIcon from "@mui/icons-material/Facebook";
import GoogleIcon from "@mui/icons-material/Google";
import TwitterIcon from "@mui/icons-material/Twitter";
function Register() {
return (
<div className="registerContainer">
<h1>Create Account</h1>
<button>
<FacebookIcon />
</button>
<button>
<GoogleIcon />
</button>
<button>
<TwitterIcon />
</button>
<Input type="text" placeholder="Username" />
<Input type="text" placeholder="email" />
<Input type="password" placeholder="Password" />
<button type="submit">Sign In</button>
</div>
);
}
export default Register;
SlidingCard.jsx
import React, { useState } from "react";
function SlidingCard() {
const [isChanged, setChange] = useState(false);
const loginPaheseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start jurney with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;
function handleClick(event) {
console.log(isChanged);
setChange(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
Screen.jsx
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen(props) {
return (
<div className="appContainer">
{props.isChanged ? <Register /> : <Login />}
<SlidingCard />
</div>
);
}
export default Screen;
英文:
I'm new to React. I'm trying to create a Login/Register Screen. I have three components called Login, Register and SlidingCard. I render these componenets on other jsx file called Screen. In SlidingCard.jsx i have a div and inside this div there are some text and button. When i clicked the button, text and button changes to login related things from register related things. Now the part that i stucked. I mentioned that when i clicked the button on SlidingCard the text changes. But with that click i want to render the Login or Register too. How can i do it?
Login.jsx
import React from "react";
import Input from "./Input";
function Login() {
return (
<div className="loginContainer">
<div className="loginChildContainer">
<h1>Welcome Back!</h1>
<p>Lorem lorem lorem lorem lorem</p>
<Input type="text" placeholder="Username" />
<Input type="password" placeholder="Password" />
<button type="submit">Sign In</button>
</div>
</div>
);
}
export default Login;
Register.jsx
import React from "react";
import Input from "./Input";
import FacebookIcon from "@mui/icons-material/Facebook";
import GoogleIcon from "@mui/icons-material/Google";
import TwitterIcon from "@mui/icons-material/Twitter";
function Register() {
return (
<div className="registerContainer">
<h1>Create Account</h1>
<button>
<FacebookIcon />
</button>
<button>
<GoogleIcon />
</button>
<button>
<TwitterIcon />
</button>
<Input type="text" placeholder="Username" />
<Input type="text" placeholder="email" />
<Input type="password" placeholder="Password" />
<button type="submit">Sign In</button>
</div>
);
}
export default Register;
SlidingCard.jsx
import React, { useState } from "react";
function SlidingCard() {
const [isChanged, setChange] = useState(false);
const loginPaheseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start jurney with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;
function handleClick(event) {
console.log(isChanged);
setChange(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
Screen.jsx
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen(props) {
return (
<div className="appContainer">
{props.isChanged ? <Register /> : <Login />}
<SlidingCard />
</div>
);
}
I checked the interner and i can't find what i'm looking for.
答案1
得分: 1
基本上在React中,当你想要改变页面上的某些东西时...你不这样做。相反,你改变一个控制页面部分的状态变量,然后React会通过更新页面来"响应"你。
所以,如果你想要一个登录组件出现,你只需创建一个showLogin状态变量,将组件包裹起来:
{showLogin && <Login/>}
然后将该变量更改为true。
英文:
Fundamentally in React, when you want to change something on the page ... you don't. Instead, you change a state variable that controls that part of the page, and then React "reacts" by updating the page for you.
So, if you want a Login component to appear, you simply make a showLogin state variable, wrap the component with it:
{showLogin && <Login/>}
and the change that variable to true.
答案2
得分: 1
由于isChanged状态在渲染Login/Register和SlidingCard之间共享,您需要将该状态“提升”到它们的共同父组件Screen。一旦您这样做了,您就可以直接在Screen内部使用isChanged,并将其和setChange传递给SlidingCard。官方React文档中的此文章更详细地解释了这个问题。
最终,您只需要对Screen.jsx和SlidingCard.jsx进行如下更改:
Screen.jsx
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen(props) {
const [isChanged, setChange] = React.useState(false);
return (
<div className="appContainer">
{isChanged ? <Register /> : <Login />}
<SlidingCard isChanged={isChanged} setChange={setChange} />
</div>
);
}
export default Screen;
SlidingCard.jsx
import React from "react";
function SlidingCard({isChanged, setChange}) {
const loginPhaseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start journey with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPhaseTexts;
function handleClick(event) {
console.log(isChanged);
setChange(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
然而,您可能还应该考虑对状态使用更合适/可读的名称,如showLogin和setShowLogin。
英文:
Since your isChanged state is shared between both rendering Login/Register and SlidingCard, you need to "lift" that state up to their common parent, Screen. Once you do that, you can use isChanged directly within Screen, and pass it and setChange down to SlidingCard. This article from the official React docs explains this issue more.
In the end, you only need to change Screen.jsx and SlidingCard.jsx like so:
Screen.jsx
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen(props) {
const [isChanged, setChange] = React.useState(false);
return (
<div className="appContainer">
{isChanged ? <Register /> : <Login />}
<SlidingCard isChanged={isChanged} setChange={setChange} />
</div>
);
}
export default Screen;
SlidingCard.jsx
import React from "react";
function SlidingCard({isChanged, setChange}) {
const loginPaheseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start jurney with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;
function handleClick(event) {
console.log(isChanged);
setChange(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
However, you should also probably consider a more appropriate/readable name for the state, such as showLogin and setShowLogin.
答案3
得分: 1
根据我的评论,我已经在一个代码沙箱项目中实现了我建议的更改(https://codesandbox.io/s/nostalgic-pond-dwrrnl)。
主要更改在 Screen.jsx 文件中:
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen() {
const [isChanged, setIsChanged] = React.useState(false);
return (
<div className="appContainer">
{isChanged ? <Register /> : <Login />}
<SlidingCard isChanged={isChanged} setIsChanged={setIsChanged} />
</div>
);
}
export default Screen;
然后在 SlidingCard 文件中通过 props 获取状态:
import React from "react";
function SlidingCard({ isChanged, setIsChanged }) {
const loginPaheseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start jurney with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;
function handleClick(event) {
console.log(isChanged);
setIsChanged(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
这就是你要的翻译结果,没有其他内容。
英文:
As per my comment, I have implemented my suggested changes in a code sandbox project (https://codesandbox.io/s/nostalgic-pond-dwrrnl).
Main changes are in Screen.jsx
import React from "react";
import Login from "./Login";
import Register from "./Register";
import SlidingCard from "./SlidingCard";
function Screen() {
const [isChanged, setIsChanged] = React.useState(false);
return (
<div className="appContainer">
{isChanged ? <Register /> : <Login />}
<SlidingCard isChanged={isChanged} setIsChanged={setIsChanged} />
</div>
);
}
export default Screen;
and then get the state as props in Sliding card
import React from "react";
function SlidingCard({ isChanged, setIsChanged }) {
const loginPaheseTexts = {
title: "Hello, Friend!",
description: "Enter your personal details and start jurney with us.",
button: "Sign Up"
};
const registerPhaseTexts = {
title: "Welcome Back",
description:
"To keep connecting with us please login with your personal info.",
button: "Sign In"
};
const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;
function handleClick(event) {
console.log(isChanged);
setIsChanged(!isChanged);
}
return (
<div>
<h1>{texts.title}</h1>
<p>{texts.description}</p>
<button onClick={handleClick}>{texts.button}</button>
</div>
);
}
export default SlidingCard;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论