react setstate未用新数组替换数组

问题描述 投票:0回答:1

与数组的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>         
        )
    }
}

javascript arrays reactjs
1个回答
0
投票

问题是您没有正确使用setState回调,它应该是一个函数。完成后,该日志将立即使用当前状态值before进行更新。

this.setState(
  { customFieldsComponents: [] }, 
  () => console.log(this.state.customFieldsComponents),
);

this.setState(
  { customFieldsComponents: updatedCustomFieldComponents },
  () => console.log(this.state.customFieldsComponents),
);

0
投票

setState的第二个参数是一个回调,但是您只是在调用console.log

更改此

 this.setState({customFieldsComponents[]},console.log(this.state.customFieldsComponents))

对此

 this.setState({customFieldsComponents[]},() => console.log(this.state.customFieldsComponents))
© www.soinside.com 2019 - 2024. All rights reserved.