Home > Blockchain >  Object value becomes undefined on button click in React
Object value becomes undefined on button click in React

Time:02-07

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;

CodePudding user response:

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!

  •  Tags:  
  • Related