Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Object value becomes undefined on button click in React

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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;

>Solution :

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!

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading