vivekh
vivekh

Reputation: 15

Creating and pushing new object into react state array

I am working on a react form with multiple form elements, and an option to repeat the whole form. Basically a add more button which adds a new form block.

To keep track of multiple forms, I created a formModel object in a different file and imported this to my react from component.

var formModel = {
    counter : 0,
    formElements : {
        text1 : '',
        text2 : '',
        select1: '',
        radio: ''
    }
};

export default formModel;

In my component which handles the form I import it and initialize the state with 1 object of this formModel, as I need to show a minimum of one form block. I have a Add mode/Remove option where I add/remove a form block.

class FormComponent extends React.Component {

    constructor(){
      super()
      this.state = {
        formList: [formModel]   
      };
    }

    addAnother(){
        let nextFormList = this.state.formList;
        nextFormList.push(formModel);
        this.setState({
            formList: nextFormList
        });
    }


    render() {
      return (
        //I map over the formList and send my form state as props into a formElement component
      );
    }
  }

My issue, is when I try to add a new object of formModel in the addAnother method into my formList array in state, it keeps adding the same initial copy of formModel.

I'm unable to create a new copy of the formModel object and keep pushing the same copy.

I'm guessing a basic JS concept of creating objects which I'm unable to implement.

Upvotes: 1

Views: 2325

Answers (1)

trixn
trixn

Reputation: 16354

Two things you should avoid when using state:

  1. Do not mutate objects in the current state. Always create new objects to update the state. You can use the spread operator for that.

  2. Calls to setState are asynchronous - don’t rely on this.state to reflect the new value immediately after calling setState. Use the callback version of setState() instead. React batches updates and when the update happens this.state does not contain the data from previously scheduled updates and may override them.

Example:

addAnother(){
    this.setState(oldState => ({
        formList: [...oldState.formList, formModel]
    }));
}

Upvotes: 4

Related Questions