React:如何使用条件渲染和React钩子来更新另一个组件的状态?

huangapple go评论75阅读模式
英文:

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 &quot;react&quot;;
import Input from &quot;./Input&quot;;

function Login() {
  return (
    &lt;div className=&quot;loginContainer&quot;&gt;
      &lt;div className=&quot;loginChildContainer&quot;&gt;
        &lt;h1&gt;Welcome Back!&lt;/h1&gt;
        &lt;p&gt;Lorem lorem lorem lorem lorem&lt;/p&gt;
        &lt;Input type=&quot;text&quot; placeholder=&quot;Username&quot; /&gt;
        &lt;Input type=&quot;password&quot; placeholder=&quot;Password&quot; /&gt;
        &lt;button type=&quot;submit&quot;&gt;Sign In&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default Login;

Register.jsx

import React from &quot;react&quot;;
import Input from &quot;./Input&quot;;
import FacebookIcon from &quot;@mui/icons-material/Facebook&quot;;
import GoogleIcon from &quot;@mui/icons-material/Google&quot;;
import TwitterIcon from &quot;@mui/icons-material/Twitter&quot;;

function Register() {
  return (
    &lt;div className=&quot;registerContainer&quot;&gt;
      &lt;h1&gt;Create Account&lt;/h1&gt;
      &lt;button&gt;
        &lt;FacebookIcon /&gt;
      &lt;/button&gt;
      &lt;button&gt;
        &lt;GoogleIcon /&gt;
      &lt;/button&gt;
      &lt;button&gt;
        &lt;TwitterIcon /&gt;
      &lt;/button&gt;
      &lt;Input type=&quot;text&quot; placeholder=&quot;Username&quot; /&gt;
      &lt;Input type=&quot;text&quot; placeholder=&quot;email&quot; /&gt;
      &lt;Input type=&quot;password&quot; placeholder=&quot;Password&quot; /&gt;
      &lt;button type=&quot;submit&quot;&gt;Sign In&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default Register;

SlidingCard.jsx

import React, { useState } from &quot;react&quot;;

function SlidingCard() {
  const [isChanged, setChange] = useState(false);

  const loginPaheseTexts = {
    title: &quot;Hello, Friend!&quot;,
    description: &quot;Enter your personal details and start jurney with us.&quot;,
    button: &quot;Sign Up&quot;
  };

  const registerPhaseTexts = {
    title: &quot;Welcome Back&quot;,
    description:
      &quot;To keep connecting with us please login with your personal info.&quot;,
    button: &quot;Sign In&quot;
  };

  const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;

  function handleClick(event) {
    console.log(isChanged);

    setChange(!isChanged);
  }

  return (
    &lt;div&gt;
      &lt;h1&gt;{texts.title}&lt;/h1&gt;
      &lt;p&gt;{texts.description}&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;{texts.button}&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default SlidingCard;

Screen.jsx

import React from &quot;react&quot;;
import Login from &quot;./Login&quot;;
import Register from &quot;./Register&quot;;
import SlidingCard from &quot;./SlidingCard&quot;;

function Screen(props) {
  return (
    &lt;div className=&quot;appContainer&quot;&gt;
      {props.isChanged ? &lt;Register /&gt; : &lt;Login /&gt;}
      &lt;SlidingCard /&gt;
    &lt;/div&gt;
  );
}

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 &amp;&amp; &lt;Login/&gt;}

and the change that variable to true.

答案2

得分: 1

由于isChanged状态在渲染Login/RegisterSlidingCard之间共享,您需要将该状态“提升”到它们的共同父组件Screen。一旦您这样做了,您就可以直接在Screen内部使用isChanged,并将其和setChange传递给SlidingCard。官方React文档中的此文章更详细地解释了这个问题。

最终,您只需要对Screen.jsxSlidingCard.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;

然而,您可能还应该考虑对状态使用更合适/可读的名称,如showLoginsetShowLogin

英文:

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 &quot;react&quot;;
import Login from &quot;./Login&quot;;
import Register from &quot;./Register&quot;;
import SlidingCard from &quot;./SlidingCard&quot;;

function Screen(props) {
  const [isChanged, setChange] = React.useState(false);

  return (
    &lt;div className=&quot;appContainer&quot;&gt;
      {isChanged ? &lt;Register /&gt; : &lt;Login /&gt;}
      &lt;SlidingCard isChanged={isChanged} setChange={setChange} /&gt;
    &lt;/div&gt;
  );
}

export default Screen;

SlidingCard.jsx

import React from &quot;react&quot;;

function SlidingCard({isChanged, setChange}) {

  const loginPaheseTexts = {
    title: &quot;Hello, Friend!&quot;,
    description: &quot;Enter your personal details and start jurney with us.&quot;,
    button: &quot;Sign Up&quot;
  };

  const registerPhaseTexts = {
    title: &quot;Welcome Back&quot;,
    description:
      &quot;To keep connecting with us please login with your personal info.&quot;,
    button: &quot;Sign In&quot;
  };

  const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;

  function handleClick(event) {
    console.log(isChanged);

    setChange(!isChanged);
  }

  return (
    &lt;div&gt;
      &lt;h1&gt;{texts.title}&lt;/h1&gt;
      &lt;p&gt;{texts.description}&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;{texts.button}&lt;/button&gt;
    &lt;/div&gt;
  );
}

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 &quot;react&quot;;
import Login from &quot;./Login&quot;;
import Register from &quot;./Register&quot;;
import SlidingCard from &quot;./SlidingCard&quot;;

function Screen() {
  const [isChanged, setIsChanged] = React.useState(false);

  return (
    &lt;div className=&quot;appContainer&quot;&gt;
      {isChanged ? &lt;Register /&gt; : &lt;Login /&gt;}
      &lt;SlidingCard isChanged={isChanged} setIsChanged={setIsChanged} /&gt;
    &lt;/div&gt;
  );
}

export default Screen;

and then get the state as props in Sliding card

import React from &quot;react&quot;;

function SlidingCard({ isChanged, setIsChanged }) {
  const loginPaheseTexts = {
    title: &quot;Hello, Friend!&quot;,
    description: &quot;Enter your personal details and start jurney with us.&quot;,
    button: &quot;Sign Up&quot;
  };

  const registerPhaseTexts = {
    title: &quot;Welcome Back&quot;,
    description:
      &quot;To keep connecting with us please login with your personal info.&quot;,
    button: &quot;Sign In&quot;
  };

  const texts = isChanged ? registerPhaseTexts : loginPaheseTexts;

  function handleClick(event) {
    console.log(isChanged);

    setIsChanged(!isChanged);
  }

  return (
    &lt;div&gt;
      &lt;h1&gt;{texts.title}&lt;/h1&gt;
      &lt;p&gt;{texts.description}&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;{texts.button}&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default SlidingCard;

huangapple
  • 本文由 发表于 2023年5月29日 02:12:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76352947.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定