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});
}