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.
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
.