Object value becomes undefined on button click in React Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Object value becomes undefined on button click in React without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I have this problem that when I render first component based on ‘switch’ case, I get the object values (string) displayed on the screen, but when I ‘switch’ to another component on ‘button’ click, the object values (string) disappears in all the components. the values comes from a single object and are passed as props to the components. I have checked the react components on the browser and found the object values becomes undefined whenever I made the first click to move to another component. I could not figure out why this is happening. I need help. Thank you.

This is the code:

This is parent component

import React, {useState} from 'react';
import OneToFive from './questionOneToFive';
import SixToTen from './questionSixToTen';

const Signup = () => {

const [fields, setFields] = useState({
    step: 1,
    qOne: 'What is the name of your father?',
    qTwo: 'What is the first state you visited in Nigeria?',
    qThree: 'What type of phone are you using?',
});

const { step } = fields;
const { qOne, qTwo} = fields;
const values = { qOne, qTwo}

    const nextStep = () => {
    const { step } = fields;
    setFields( {step : step + 1} );

}

 const prevStep = () => {
    const { step } = fields;
    setFields( {step: step - 1} );

}

switch(step) {
    case 1:
        return (
            <OneToFive
            nextStep={nextStep}
            values={values}
            />
        );
    case 2:
        return (
            <SixToTen
            nextStep={nextStep}
            prevStep={prevStep}
            values={values}
            />
        );
    case 3: 
        return <h1>Eleven to Fifteen</h1>
    case 4: 
        return <h1>Sixteen to Twenty</h1>
    default:
        return <h1>Error page not found</h1>
}
    
}

export default Signup; 

This is the first component.

const OneToFive = ({nextStep, values}) => {

const contee = (e) => {
    e.preventDefault();
    nextStep();
}

return (
    <div className="bg-green-200 mx-auto my-10 w-2/4 p-10 shadow-lg shadow-green-500 rounded-lg">
        <h3><span className="font-bold">Q 1:</span> {values.qOne}</h3>
        <div className="my-3">
            <input type="radio" name="mathQOne" value="abubakar"/>
            <label htmlFor=""> abubakar</label>
            <br />
            <input type="radio" name="mathQOne" value="usman"/>
            <label htmlFor=""> usman</label>
            <br />
            <input type="radio" name="mathQOne" value="shehu"/>
            <label htmlFor=""> shehu</label>
            <br />
            <input type="radio" name="mathQOne" value="bello"/>
            <label htmlFor=""> bello</label>
        </div>
}
export default OneToFive;

This is the second component

const SixToTen = ({nextStep, prevStep, values}) => {

 const contee = (e) => {
    e.preventDefault();
    nextStep();
}

const prev = (e) => {
    e.preventDefault();
    prevStep();
}

return (
 <h3><span className="font-bold">Q 2:</span> {values.qTwo}</h3>
        <div className="my-3">
            <input type="radio" name="mathQTwo" value="abuja"/>
            <label htmlFor=""> abuja</label>
            <br />
            <input type="radio" name="mathQTwo" value="kaduna"/>
            <label htmlFor=""> kaduna</label>
            <br />
            <input type="radio" name="mathQTwo" value="maiduguri"/>
            <label htmlFor=""> maiduguri</label>
            <br />
            <input type="radio" name="mathQTwo" value="kano"/>
            <label htmlFor=""> kano</label>
        </div>

   <div className="flex flex-row gap-3">
        <div className="flex flex-1 justify-start">
             <button className="bg-green-500 text-white p-3 mt-10 rounded-lg shadow-sm shadow-pink-600" onClick={prev}>Previous</button>
        </div>
       
       <div className="flex flex-1 justify-end">
             <button className="bg-green-500 text-white p-3 mt-10 rounded-lg shadow-sm shadow-pink-600" onClick={contee}>Next</button>
       </div>
       
    </div>
        
    </div>
   
)
}


export default SixToTen;

Answer

Your nextStep and prevStep functions are both replacing your original fields state variable with an object with nothing but step.

In other words, you start off with fields set to:

{
    step: 1,
    qOne: 'What is the name of your father?',
    qTwo: 'What is the first state you visited in Nigeria?',
    qThree: 'What type of phone are you using?',
}

Then, when you call nextStep, it does setFields({step: step + 1}), so you end up with fields being:

{
  step: 2
}

I think what you want here is to change the step, but leave the other properties unchanged. Try these functions instead:

const nextStep = () => {
    const { step } = fields;
    setFields( {...fields, step: step + 1} );
};

const prevStep = () => {
    const { step } = fields;
    setFields( {...fields, step: step - 1} );
};

Using the spread operator, all properties from the fields are copied to the new value, and then the step is incremented/decremented.

You could achieve the same without the spread operator like this:

const nextStep = () => {
    const { step, qOne, qTwo, qThree } = fields;
    setFields( {step: step + 1, qOne, qTwo, qThree} );
};

const prevStep = () => {
    const { step, qOne, qTwo, qThree } = fields;
    setFields( {step: step - 1, qOne, qTwo, qThree} );
};

This is perhaps easier to understand, but it’s also more verbose, especially if you ever have more than three questions!

We are here to answer your question about Object value becomes undefined on button click in React - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji