Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why did I need to wrap the state in brackets to assign it to a variable in ReactJs?

I was trying to build a simple Todo App with a currentTodo and an array of pastTodos.

I was unable to push currentTodo to pastTodo using this code here.

  handleClick(e) {
    e.preventDefault();
    let pastTodos = this.state.pastTodos;
    pastTodos.push(this.state.currentTodo);
    this.setState({ pastTodos: pastTodos, currentTodo: "" });
  }

and was only able to do by changing this line

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

let pastTodos = this.state.pastTodos;

to this

let pastTodos = [this.state.pastTodos];

Why would this be? And is this the best way to do this?

Below is all of my code for greater context.

import React from 'react';

class TodoInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentTodo: "", 
      pastTodos: []
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleChange(e) {
    e.preventDefault();
    const currentTodo = e.target.value;
    this.setState({ currentTodo: currentTodo})
  }

  handleClick(e) {
    e.preventDefault();
    let pastTodos = [this.state.pastTodos];
    pastTodos.push(this.state.currentTodo);
    this.setState({ pastTodos: pastTodos, currentTodo: "" });
  }

  render () {
    return (
      <div>
        <input onChange={this.handleChange} type="text" value={this.state.currentTodo}/>
        <br></br>
        <button onClick={this.handleClick}> Add Todo </button>
      </div>
    ); 
  }
}

export default TodoInput;

>Solution :

I highly doubt this is "working":

let pastTodos = [this.state.pastTodos];

At the very least, it’s probably producing a bug you haven’t noticed yet. Because this is creating a new array with only one element, that element being the value of this.state.pastTodos.

For example, look at the initial value of that state:

pastTodos: []

So what are you updating it to? this:

let pastTodos = [[]];

Then you push a value to it, resulting in this:

[[], someValue]

If you perform that operation again, you get this:

[[[], someValue], anotherValue]

This probably isn’t the structure you want.


At a high level, you don’t want to mutate state in React. Doing this with an array:

let pastTodos = this.state.pastTodos;

Just creates another reference to the same array. And then you mutate that array:

pastTodos.push(this.state.currentTodo);

Instead of creating a reference to the same array, create a new array:

let pastTodos = [...this.state.pastTodos];

This creates a brand new array and uses the spread syntax to populate it with the items of the array in state. Now you’re not modifying that state array but rather just modyfing a locally defined array here:

pastTodos.push(this.state.currentTodo);

Then you can use that locally defined array to update state as you currently do.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading