Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

138
Vistas
React Components conditional rendering, problems with tertiary operator in a handle click function rendering wrong component

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>
      </>)
}
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

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");
  };
about 4 years ago · Juan Pablo Isaza Denunciar

0

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);
  };
about 4 years ago · Juan Pablo Isaza Denunciar

0

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

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda