Home > Net >  Handling change for dynamic input field in components
Handling change for dynamic input field in components

Time:09-27

The state of array values is not changing i have tried many times but still not succeeded is there a way that i missed somehow here is the attached code highlighting the problem. If anyone can help it would be much appreciated.

Class component handling form stepper

 constructor(props) {
    super(props);
    this.state = {
      step: 1,
      propertyID:0,
      responseMessage:"",    
      loading:false,
      name:"",
      address: "",
      county:"",
      city: "",
      zipcode: "",
      type: "",
      specifictype: "",
      formValues:[{beds:"",rent:"",numUnits:0,squarefeet:""}]
    };
  }
handleFormChange(i, e) {
    let formValues = this.state.formValues;    
    console.log(formValues);
    formValues[i][e.target.name] = e.target.value;
    this.setState({ formValues });
  }
  render() {
    const { step } = this.state;
    const {
      address,
      name,
      specifictype,
      city,
      county,
      zipcode,
      type,
      formValues,
      responseMessage
    } = this.state;
    const values = {
      address,
      name,
      specifictype,
      city,
      zipcode,
      type,
      county,
      formValues,
      responseMessage
    } ;

    switch (step) {
      
      
      case 3:
        return(
            <PropertyType
                values={values}
                add={this.addFormFields.bind(this)}
                remove = {this.removeFormFields.bind(this)}
                handleChange={this.handleFormChange}
                prevStep={this.prevStep}
                nextStep={this.getandSend}

            />
        )
     
    }
  }

then here is the code of the component that handles the dynamic input fields.I had to reduce the code other parts are working fine do not worry about values,add,remove,prevStep and next step those are working just fine the problem is how i handle the change

function PropertyType({values,add,remove,handleChange,prevStep,nextStep}) {

return(
<>
 <form action="">
                            {values.formValues.slice(0,5).map((element, index) => (
                            <div className="w-full md:w-9/12 flex mx-auto">
                                <div className="mb-6 mr-3">
                                    <label
                                        className="block mb-2 text-coolGray-800"
                                        htmlFor=""
                                    >
                                        Beds
                                    </label>
                                    <select defaultValue={element.beds} onChange={e => handleChange(index, e)} className="block w-full p-3 leading-5 text-coolGray-900 border border-coolGray-200 rounded-lg shadow-md placeholder-coolGray-400 focus:outline-none focus:ring-2 focus:ring-color-main focus:ring-opacity-50 bg-white" aria-label="Default select example">
                                        <option selected>Select bedrooms</option>
                                        <option value="0">Studio</option>
                                        <option value="1">One</option>
                                        <option value="2">Two</option>
                                        <option value="3">Three</option>
                                        <option value="4 ">More than 4</option>
                                    </select>
                                </div>
                                <div className="mb-2 mr-3">
                                    <label
                                        className="block mb-2 text-coolGray-800 font-medium"
                                        htmlFor=""
                                    >
                                        Number of units
                                    </label>
                                    <input
                                        defaultValue={element.numUnits}
                                        onChange={e => handleChange(index, e)}
                                        className="appearance-none block w-full p-3 leading-5 text-coolGray-900 border border-coolGray-200 rounded-lg shadow-md placeholder-coolGray-400 focus:outline-none focus:ring-2 focus:ring-color-main focus:ring-opacity-50"
                                        type="number"
                                        placeholder="10"
                                    />
                                </div>
                                <div className="mb-2 mr-3">
                                    <label
                                        className="appearance-none block mb-2 text-coolGray-800 font-medium"
                                        htmlFor=""
                                    >
                                        Squarefeet
                                    </label>
                                    <input
                                        defaultValue={element.squarefeet}
                                        onChange={e => handleChange(index, e)}
                                        className="appearance-none block w-full p-3 leading-5 text-coolGray-900 border border-coolGray-200 rounded-lg shadow-md placeholder-coolGray-400 focus:outline-none focus:ring-2 focus:ring-color-main focus:ring-opacity-50"
                                        type="number"
                                        placeholder="2000"
                                    />
                                </div>
                                <div className="mb-2 mr-3">
                                    <label
                                        className="block mb-2 text-coolGray-800 font-medium"
                                        htmlFor=""
                                    >
                                        Rent
                                    </label>
                                    <input
                                        defaultValue={element.rent}
                                        onChange={e => handleChange(index, e)}
                                        className="appearance-none block w-full p-3 leading-5 text-coolGray-900 border border-coolGray-200 rounded-lg shadow-md placeholder-coolGray-400 focus:outline-none focus:ring-2 focus:ring-color-main focus:ring-opacity-50"
                                        type="number"
                                        placeholder="30,000"
                                    />
                                </div>
                                {
                                    index ?<div className="mb-2 mr-3 mt-8">
                                            <button  className=" inline-block py-3 px-7 mb-4 w-full text-base text-white font-medium text-center leading-6 bg-red-500/50 rounded-md shadow-sm
                                            " onClick={remove}>Remove</button> </div>

                                        : null
                                }

                            </div>
                            ))}

</>

)

}

CodePudding user response:

You need to update the reference of the formValues array with spread operator.

handleFormChange(i, e) {
    let formValues = this.state.formValues;    
    console.log(formValues);
    formValues[i][e.target.name] = e.target.value;
    this.setState({ formValues: [...formValues ]});
}

CodePudding user response:

you have to make a copy of reference and then update as below:

handleFormChange = (i, e) => {
        const formValues = [...this.state.formValues]; 
        const res = formValues.map((val,idx)=>{
           if(idx == i){
             return ({...val, [e.target.name]: e.target.value})
           }
           return val
        }) 
        this.setState({ ...this.state, formValues: res});
    }
  • Related