Reputation: 1527
It's about setState of an array.
React setstate is not replacing the array with new array
You can see that, I have customFieldsComponents in the constructor state.
In the addCustomField() function, I'm adding some elements in the array with the unique keys.
Now,In the removeCustomField() function, when I want to remove an element from the array, by setting new array of the filtered elements, its not replacing the customFieldsComponents array.
The problem is in the removeCustomField() function.
https://gist.github.com/akgarg007/ba8ade35b64b423def767fdfda263744
If you see the gist, I'm having issues on line number 98.
import React, { Component } from 'react';
// Import Custom Components
import TextField from '../CustomFieldComponents/TextField';
import DateField from '../CustomFieldComponents/DateField';
import RadioField from '../CustomFieldComponents/RadioField';
export const CustomFieldContext = React.createContext();
export class CustomFieldProvider extends Component {
constructor(props) {
super(props)
this.state = {
// PhoneFieldCounter: 1,
// phoneComponents: [],
customFieldSelected:'',
customFieldsArray:[],
customFieldsComponents:[],
}
this.addCustomField = this.addCustomField.bind(this);
this.removeCustomField = this.removeCustomField.bind(this);
this.handleCustomFieldChange = this.handleCustomFieldChange.bind(this);
}
addCustomField(){
/***
* Add all selected fields in the customFieldsArray array.
* If custom field is already selected, it can't be selected again.
*
* We can try to update the select dropdown list later on.
*/
if(this.state.customFieldSelected.length == 0){
// If no custom field selected!
alert('Please select a field!');
return NULL;
}else if(this.state.customFieldSelected == 'Select'){
// If no custom field selected!
alert('Please select a field!');
return NULL;
}else{
// check if field is already inserted in the addray or not
var n = this.state.customFieldsArray.includes(this.state.customFieldSelected);
if(n != true){
console.log(this.state.customFieldSelected);
this.state.customFieldsArray.push(this.state.customFieldSelected);
}else{
// console.log(this.state.customFieldsArray);
// console.log('field already selected, select another');
alert('This field already selected, select another');
return NULL;
}
// If selected field is a Text, then add new TextField in the custom Fields array
if(
this.state.customFieldSelected == 'PersonalID' ||
this.state.customFieldSelected == 'Website' ||
this.state.customFieldSelected == 'LinkedIn' ||
this.state.customFieldSelected == 'Facebook' ||
this.state.customFieldSelected == 'Twitter' ||
this.state.customFieldSelected == 'Skype'
){
var newField = (
<TextField key={this.state.customFieldSelected} fieldName = {this.state.customFieldSelected} />
);
}else if(this.state.customFieldSelected == 'Birth Date'){
var newField = (
<DateField key={this.state.customFieldSelected} fieldName = {this.state.customFieldSelected} />
);
}
else if(this.state.customFieldSelected == 'Gender'){
const fieldNames = ['male','female'];
var newField = (
<RadioField key={this.state.customFieldSelected} fieldName = {this.state.customFieldSelected} fieldNames={fieldNames} />
);
}
else if(this.state.customFieldSelected == 'Decision Maker'){
const fieldNames = ['yes','no'];
var newField = (
<RadioField key={this.state.customFieldSelected} fieldName = {this.state.customFieldSelected}
fieldNames={fieldNames} />
);
}
this.setState(prevState => ({
customFieldsComponents: [...prevState.customFieldsComponents, newField]
}))
// If selected field is a Textarea, then add new TextareaField in the custom Fields array
// If selected field is a Radio, then add new RadioField in the custom Fields array
// If selected field is a Dropdown, then add new DropdownField in the custom Fields array
}
}
removeCustomField(fieldName){
// First filter the field you want to remove from the array.
// Then replace the old array with the new updated array.
var updatedCustomFieldComponents = this.state.customFieldsComponents.filter(element => element.key != fieldName);
this.setState({ customFieldsComponents: [] }, console.log(this.state.customFieldsComponents))
// this.setState({ customFieldsComponents: updatedCustomFieldComponents }, console.log(this.state.customFieldsComponents))
}
handleCustomFieldChange(field){
this.setState({
customFieldSelected: field
});
}
render() {
return (
<CustomFieldContext.Provider
value={{
state:this.state,
addCustomField: this.addCustomField,
removeCustomField:(fieldName)=>{
this.removeCustomField(fieldName)
},
handleCustomFieldChange: (e)=>{
this.handleCustomFieldChange(e.target.value)
}
}}
>
{this.props.children}
</CustomFieldContext.Provider>
)
}
}
Upvotes: 1
Views: 1715
Reputation: 10085
The second parameter of the setState is a callback, but you're just calling the
console.log
change this
this.setState({customFieldsComponents[]},console.log(this.state.customFieldsComponents))
to this
this.setState({customFieldsComponents[]},() => console.log(this.state.customFieldsComponents))
Upvotes: 1
Reputation: 203457
The issue is you aren't using the setState callback correctly, it should be a function. As you've done, the log would fire immediately with the current state value, before it's been updated.
this.setState(
{ customFieldsComponents: [] },
() => console.log(this.state.customFieldsComponents),
);
and
this.setState(
{ customFieldsComponents: updatedCustomFieldComponents },
() => console.log(this.state.customFieldsComponents),
);
Upvotes: 4