Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

123
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!