1

I am trying to update my code: https://repl.it/@colegonzales1/HeftyJoyfulAbilities

I am trying to make my handleToggle function work properly. It is blank now for the sake of tinkering, but I have spent the last 2-3 hours trying to make it work to my own knowledge but I cannot figure out how to access a specific item in state. I know how to overwrite it all, but that is not what I want to do. Say I have:

this.state = {
  todos: [
    {
      title: 'Wash car',
      id: 1,
      done: false
    },
    {
      title: 'Go shopping',
      id: 2,
      done: false
    }
  ],
  inputValue: ''
}

How can I ONLY change the value of done on the 'Go shopping' todo, to true?

0

2 Answers 2

1

Use an array.map to toggle the done flag only on the element which matches the clicked id as follows. The other properties of the todo are copied with an object spread:

handleToggle (e) {
  const id = parseInt(e.target.id,10)
  this.setState((prevState) => ({
    todos: prevState.todos.map(t => t.id === id ? {...t, done: !t.done} : t)
  })) 
}
Sign up to request clarification or add additional context in comments.

2 Comments

Why do you use todos: prevState? Why not just say todos: this.state.todos.map?
@ColeGonzales prevState is the new recommended way of accessing the current state before a state change. teamtreehouse.com/community/…
1

You can find the index of the object with the given id with findIndex and create a new array with a copy of this object in it with its done flag toggled.

Example

class App extends React.Component {
  state = {
    todos: [
      {
        title: "Wash car",
        id: 1,
        done: false
      },
      {
        title: "Go shopping",
        id: 2,
        done: false
      }
    ],
    inputValue: ""
  };

  handleToggle = id => {
    this.setState(prevState => {
      const todos = [...prevState.todos];
      const todoIndex = todos.findIndex(todo => todo.id === id);

      todos[todoIndex] = { ...todos[todoIndex], done: !todos[todoIndex].done };

      return { todos };
    });
  };

  render() {
    return (
      <div>
        <div>{JSON.stringify(this.state)}</div>
        <button onClick={() => this.handleToggle(2)}>
          Toggle todo with id 2
        </button>
      </div>
    );
  }
}

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

<div id="root"></div>

Comments

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.