React Components条件渲染,句柄单击函数中的三级运算符渲染错误组件的问题

发布于 2025-01-17 17:34:37 字数 1360 浏览 0 评论 0原文

我是一名新开发人员,这是我关于堆栈溢出的第一个问题,所以请耐心等待。我希望这是正确的社区和正确的提问方式(如果有方法可以改善我的询问,请告诉我)。

所以我有一个 React 功能组件,可以有条件地呈现三种形式。我采用了一个大表单并将其分成三个部分,以便当用户单击 div 中的下一个按钮时,他们将被带到下一个表单,下一个按钮调用一个单击处理程序函数,该函数使用状态来确定应显示哪个表单使用第三级操作员来检查状态。我的问题是,处理程序函数的逻辑在第一次单击后显示第三种形式,而不是我所期望的第二种形式,是否有更简单的解决方法或如何解决此问题?我有下面的代码并尽可能地简化它,以尝试仅显示我正在处理的逻辑问题。

//代码

import { useState } from "react";   


export default function PinFormTest(){

    const [showFirstForm, setShowFirstForm] = useState(true)
    const [showSecondForm, setShowSecondForm] = useState(false)
    const [showThirdForm, setShowThirdForm] = useState(false)

    const handleNextForm = () => {
         showFirstForm ? setShowFirstForm(false) && setShowSecondForm(true):
            showSecondForm ? setShowSecondForm(false) && setShowThirdForm(true):
                console.log("error")

    }

    return(
      <>
        <div className="formContainer">
          {showFirstForm ? 
            (<>firstForm</>): showSecondForm ? (<>secondForm</>): (<>thirdForm</>)
          }
        </div>
        <div>
          <button onClick={() => handlePreviousForm()}>Previous</button>
          <button onClick={() => handleNextForm()}>Next</button>
        </div>
      </>)
}

I'm a new developer and this is my first question on stack overflow so please be patient. I hope this is the right community and the correct way to ask a question (let me know if there are ways I can imporve my inquiries).

So I have a React functional compoenent that renders three forms conditionally. I took one big form and broke it into three sections so that when the user clicks the next button in the div, they are taken to the next form and the next button calls a click handler function that uses state to determine which form should be shown with a tertiary operator to check the state. My problem is that the logic of the handler function shows the third form after first click instead of the second as I would expect, any idea of a simpler work around or how to fix this? I have the code below and simplified it as much as I could to try and just show the logic issue I'm dealing with.

//Code

import { useState } from "react";   


export default function PinFormTest(){

    const [showFirstForm, setShowFirstForm] = useState(true)
    const [showSecondForm, setShowSecondForm] = useState(false)
    const [showThirdForm, setShowThirdForm] = useState(false)

    const handleNextForm = () => {
         showFirstForm ? setShowFirstForm(false) && setShowSecondForm(true):
            showSecondForm ? setShowSecondForm(false) && setShowThirdForm(true):
                console.log("error")

    }

    return(
      <>
        <div className="formContainer">
          {showFirstForm ? 
            (<>firstForm</>): showSecondForm ? (<>secondForm</>): (<>thirdForm</>)
          }
        </div>
        <div>
          <button onClick={() => handlePreviousForm()}>Previous</button>
          <button onClick={() => handleNextForm()}>Next</button>
        </div>
      </>)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

纵山崖 2025-01-24 17:34:37

您应该通过编写逗号分隔的语句来编写三元运营商中的多行语句。您的正确代码将是;

  const handleNextForm = () => {
    showFirstForm
      ? (setShowFirstForm(false), setShowSecondForm(true))
      : showSecondForm
      ? (setShowSecondForm(false), setShowThirdForm(true))
      : console.error(error);
  };

You should write multiple lines of statements in ternary operators by writing comma separated statements. Your correct code will be;

  const handleNextForm = () => {
    showFirstForm
      ? (setShowFirstForm(false), setShowSecondForm(true))
      : showSecondForm
      ? (setShowSecondForm(false), setShowThirdForm(true))
      : console.error(error);
  };
世界等同你 2025-01-24 17:34:37

在这种情况下,尽量避免使用三元运算符,因为它会导致可读性等问题,从而使以后的调试变得更加困难。

const handleNextForm = () => {
    if (showFirstForm) {
      setShowFirstForm(false);
      setShowSecondForm(true);
      return;
    }

    if (showSecondForm) {
      setShowSecondForm(false);
      setShowThirdForm(true);
      return;
    }
    console.log("error");
  };

In such situations try to avoid using the ternary operator because it will cause issues like readability, which makes it harder to debug later on.

const handleNextForm = () => {
    if (showFirstForm) {
      setShowFirstForm(false);
      setShowSecondForm(true);
      return;
    }

    if (showSecondForm) {
      setShowSecondForm(false);
      setShowThirdForm(true);
      return;
    }
    console.log("error");
  };
独孤求败 2025-01-24 17:34:37

您正在使用 && 并且仅当 lefttrue 时才会评估 right

&& // 示例

所以您正在使用 setShowFirstForm(false) && setShowSecondForm(true) 因此,这将首先评估 setShowFirstForm(false) ,您不会从中返回任何内容,因此返回值将为 undefined 这是一个 虚假值。因此,这将评估 setShowSecondForm(true)

解决方案 1

您可以在此处使用 ,Codesandbox 演示

showFirstForm
  ? (setShowFirstForm(false), setShowSecondForm(true))
  : showSecondForm
  ? (setShowSecondForm(false), setShowThirdForm(true))
  : console.log("error");

解决方案2

您可以使用简单的if-else分支,Codesandbox demo

if (showFirstForm) {
  setShowFirstForm(false);
  setShowSecondForm(true);
} else if (showSecondForm) {
  setShowSecondForm(false);
  setShowThirdForm(true);
} else {
  console.log("error");
}

解决方案3

这里可以使用Map来创建地图对于表单级别和要渲染的组件,如果表单中的阶段增加,其他解决方案将不会是更好的解决方案。 Codesandbox 链接

import React, { useState } from "react";
import FirstForm from "./components/FirstForm";
import SecondForm from "./components/SecondForm";
import ThirdForm from "./components/ThirdForm";

const formComponentsArr = [FirstForm, SecondForm, ThirdForm];
const formComponents = new Map(
  formComponentsArr.map((comp, i) => {
    return [i + 1, comp];
  })
);

export default function App() {
  const [level, setLevel] = useState(1);

  function handleNextForm() {
    if (level !== formComponents.size) {
      setLevel((l) => l + 1);
    }
  }

  function getComponent() {
    const comp = formComponents.get(level);
    return comp ? comp() : null;
  }

  return (
    <>
      <div className="formContainer">{getComponent()}</div>
      <div>
        {/* <button onClick={() => handlePreviousForm()}>Previous</button> */}
        <button onClick={() => handleNextForm()}>Next</button>
      </div>
    </>
  );
}

解决方案4 - 最佳解决方案

创建一个自定义挂钩,用于处理下一个上一个。您所要做的就是传递需要顺序渲染的组件数组。 Codesandbox 链接

You are using && and it will only evaluate right only if the left is true

left && right // Example

So you are using setShowFirstForm(false) && setShowSecondForm(true) so this will first evaluate setShowFirstForm(false) from which you are not returning anything so the return value will be undefined which is a falsy value. So this will evaluate setShowSecondForm(true)

Solution 1

You can use , here as: Codesandbox demo

showFirstForm
  ? (setShowFirstForm(false), setShowSecondForm(true))
  : showSecondForm
  ? (setShowSecondForm(false), setShowThirdForm(true))
  : console.log("error");

Solution 2

You can use simple if-else branching, Codesandbox demo

if (showFirstForm) {
  setShowFirstForm(false);
  setShowSecondForm(true);
} else if (showSecondForm) {
  setShowSecondForm(false);
  setShowThirdForm(true);
} else {
  console.log("error");
}

Solution 3

You can use Map here to create a map for form level and the component to render, other solution won't be a better solution if the stages in form increases. Codesandbox link

import React, { useState } from "react";
import FirstForm from "./components/FirstForm";
import SecondForm from "./components/SecondForm";
import ThirdForm from "./components/ThirdForm";

const formComponentsArr = [FirstForm, SecondForm, ThirdForm];
const formComponents = new Map(
  formComponentsArr.map((comp, i) => {
    return [i + 1, comp];
  })
);

export default function App() {
  const [level, setLevel] = useState(1);

  function handleNextForm() {
    if (level !== formComponents.size) {
      setLevel((l) => l + 1);
    }
  }

  function getComponent() {
    const comp = formComponents.get(level);
    return comp ? comp() : null;
  }

  return (
    <>
      <div className="formContainer">{getComponent()}</div>
      <div>
        {/* <button onClick={() => handlePreviousForm()}>Previous</button> */}
        <button onClick={() => handleNextForm()}>Next</button>
      </div>
    </>
  );
}

Solution 4 - BEST SULUTION

Create a custom hook as which will handle the next and previous. All you have to do is to pass an array of components that needs to be rendered sequentially. Codesandbox link

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文