0

I wanted to store array objects in react state. I don't know what I'm missing but my code is not working. Here is my code below :

export default class Groups extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tabledata: []
    }
  }

  componentDidMount() {
    this.setState({
      tabledata: [...this.state.tabledata, {"name": "name1"}]
    })

    console.log("HI")
    console.log(this.state.tabledata)
  }
}

The console log return empty state not storing anyting in state array.. Please suggest what's wrong here. Thank you in advance..

2
  • 1
    setState is asynchronous. Commented Jul 9, 2019 at 11:36
  • can you please explain more ? Commented Jul 9, 2019 at 11:38

2 Answers 2

1

You can push the object(s) into the array:

    export default class Groups extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        tabledata: []
      }
    }

    componentDidMount() {
      this.setState({
        // tabledata: [...this.state.tabledata, {"name": "name1"}]
            tabledata: this.state.tabledata.push({"name": "name1"})
      })

      console.log("HI")
      console.log(this.state.tabledata)
    }
Sign up to request clarification or add additional context in comments.

Comments

1

There are two separate problems there, but both spring from the same cause: State updates are asynchronous.

So the two problems are:

  1. You're setting state based on existing state by passing an object into setState. That could set stale state. When updating state based on existing state, you must use the callback version of setState.

  2. You're logging state immediately after calling setState. That won't see the updated state, because the update is asynchronous. Instead, log it in the completion callback (if you need to do something with it; normally, you don't need this, just allow React to re-render, which it will do by default).

Here are those corrections applied to your code:

export default class Groups extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tabledata: []
    }
  }

  componentDidMount() {
    this.setState(
      // Update callback receives the current state. Here I'm picking
      // `tabledata` from it via destructuring
      ({tabledata}) => ({
        tabledata: [...tabledata, {"name": "name1"}]
      }),
      // Completion callback
      () => {
        console.log("HI")
        console.log(this.state.tabledata)
      }
    )
  }
}

Live Example:

class Groups extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tabledata: []
    }
  }

  componentDidMount() {
    this.setState(
      ({tabledata}) => ({
        tabledata: [...tabledata, {"name": "name1"}]
      }),
      () => {
        console.log("HI")
        console.log(this.state.tabledata)
      }
    )
  }
  
  render() {
    return this.state.tabledata.map(({name}) => <div>{name}</div>);
  }
}

ReactDOM.render(<Groups />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

Again, though, normally you don't need or want to use the completion callback, so:

export default class Groups extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tabledata: []
    }
  }

  componentDidMount() {
    this.setState(({tabledata}) => ({
      tabledata: [...tabledata, {"name": "name1"}]
    }));
  }
}

3 Comments

Hi, I tried this option before, but it was returning empty. So now also it's returning empty again
@David - The above definitely works, see the live example. I did have a typo (tableData instead of tabledata), perhaps you also had a typo?
yes I observed the typo, I corrected it then also it is returning me blank. And thank you for live example. I'll go through my code once again..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.