与数组的setState有关。
React setstate没有用新数组替换数组
您可以看到,我在构造函数状态下具有customFieldsComponents。
在addCustomField()函数中,我使用唯一键在数组中添加了一些元素。
现在,在removeCustomField()函数中,当我想从数组中删除一个元素时,通过设置已过滤元素的新数组,它不会替换customFieldsComponents数组。
问题出在removeCustomField()函数中。
https://gist.github.com/akgarg007/ba8ade35b64b423def767fdfda263744
如果看到要点,我在第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>
)
}
}
问题是您没有正确使用setState回调,它应该是一个函数。完成后,该日志将立即使用当前状态值before进行更新。
this.setState(
{ customFieldsComponents: [] },
() => console.log(this.state.customFieldsComponents),
);
和
this.setState(
{ customFieldsComponents: updatedCustomFieldComponents },
() => console.log(this.state.customFieldsComponents),
);
setState的第二个参数是一个回调,但是您只是在调用
console.log
更改此
this.setState({customFieldsComponents[]},console.log(this.state.customFieldsComponents))
对此
this.setState({customFieldsComponents[]},() => console.log(this.state.customFieldsComponents))