英文:
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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论