3

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.

3
  • Just to make sure I understand, you want to be able to toggle between the <Register /> and <Login /> from something within <SlidingCard />? Commented May 28, 2023 at 18:20
  • You're making some basic mistakes. Apparently Screen is the parent component then how are you getting isChanged from the props? If you want to achieve something that you mentioned then you should make a state variable in Screen.jsx, then pass that state to the sliding card as a prop and also use it to show respective Login or Register screens. Commented May 28, 2023 at 18:23
  • Yes, I am trying to be able to toggle between them. Commented May 28, 2023 at 18:38

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

When I do it like that, only the SlidingCard component is visible. And when I clicked the button on the component it gives me error says "setChange is not a function". could you help me more?
@GörkemTandoğan are you sure you are correctly passing the function down to SlidingCard and extracting it from props there? Here is a working version of your code: codesandbox.io/s/clever-clarke-w0ns04
I think you were missing export default in a few files.
1

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.

Comments

1

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.