CodeToday: Learning By Doing with React Hooks
Tags: javascript, react, todayilearned
Published: 2020-03-12 16:38:33

---
title: CodeToday: Learning By Doing with React Hooks
published: true
description: My first project with Hooks
tags: javascript, react, todayilearned
---

# The Gist

I haven't had a chance to implement React's state hooks in a project yet, so I quickly found a tutorial on [Scotch.io](https://scotch.io/tutorials/build-a-react-to-do-app-with-react-hooks-no-class-components) to dive into.
I wanted to document my journey through the project and questions I hit as I start using hooks.

# The Journey

1) __Question:__ First question I had as I built the below code, was on the syntax. Specifically, using `useState([])`

```js
function App() {
  const [todos, setTodos] = useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);
}
```
__Answer:__ Just some regular [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), which "makes it possible to unpack values from arrays, or properties from objects, into distinct variables."

I was used to object destructuring:
```js
const person = {first: 'Wes'}
const first = person.first; // 'Wes'
```

But with array destructuring, we don't have to worry about keys and values jumbling up our code. I quickly found a very clear post by [Sarah Chima](https://dev.to/sarah_chima), called [Destructuring Assignment in ES6- Arrays](https://dev.to/sarah_chima/destructuring-assignment---arrays-16f).
Two key basic things are that this array destructuring helps in grabbing our elements __based on the array's index__. And that __commas__ help us skip over elements and grab the next element.

```js
  var sentence = ["Kurt", "likes", "programming"];
  var [firstWord,, lastWord] = sentence;
  console.log(lastWord) // programming
```

So now, when I map over my `todo` array, the first element would look something like:
```js
  console.log(todos[0]); // {text: "Learn about React"}
```

Now, my app is displaying a list of todos

![todolist](https://dev-to-uploads.s3.amazonaws.com/i/v11mqternzklqs7m7xze.png)

2) __Question:__ How to add items to my list?

```js
const App = () => {
  //useState: 2 variables, name them anything.
  // firstVar = value || this.state
  // secondVar = function to update value || this.setState
  const [todos, setTodos] = useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);

  const addTodo = text => {
    // spread operaotor = to create a copy of array
    // {text} = from TodoForm/form/input type=text
    const newTodos = [...todos, { text }]; //needs to be object
    setTodos(newTodos);
  };

  console.log(todos); // {text: "Learn about React"}

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo key={index} index={index} todo={todo} />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
};
```
__Answer:__ Where does the magic happen? Well first I had to create a TodoForm component. Still dealing with functional components and hooks, I just added the value for my variable, which will be blank at first. An onChange function was added into the input field, which then passes the value to the `addTodo` function that we're getting from `App's` state hook declaration. And finally we reset the value to be black with our `setValue` function call that works in the same way as `setState` does within Class components. 



```js
import React, { useState } from "react";

const TodoForm = ({ addTodo }) => {
  const [value, setValue] = useState("");

  const handleSubmit = e => {
    e.preventDefault();
    if (!value) return;
    addTodo(value);
    setValue("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        className="input"
        value={value}
        onChange={e => setValue(e.target.value)}
      />
    </form>
  );
};

export default TodoForm;
```

Then inside of our app, after importing our `TodoForm`component, we pass it the `addToDo` function as a prop. Let's take a look at that function. Here I'm pulling in the user's text, which is a property on our input field. I create a variable, and pass in a copy of my `todos` array with the spread operator. The second variable in my array is the text we will adding onto our array, and thus our list of tasks.

```js
  const addTodo = text => {
    // spread operaotor = to create a copy of array
    // {text} = from TodoForm/form/input type=text
    const newTodos = [...todos, { text }]; //needs to be object
    setTodos(newTodos);
  };
``` 

3) __Question:__ How do I update my list once I've completed a task?

Well most of the work for updating a task as complete is being done in the following callback function, inside my App.js file:

```js
  const completedToDo = (index) => {
    // array holds copt of task list array
    const newTodos = [...todos];
    // find item by its index in array
    // access the isCompleted property

    newTodos[index].isCompleted === false
      ? (newTodos[index].isCompleted = true)
      : (newTodos[index].isCompleted = false);

    // set ToDo list to alrered array that was copied
    setTodos(newTodos);
  };
```

__Answer:__ It bothered me that I could only mark a task as complete once and not undo it according to the tutorial so I added a ternary to toggle my `isCompleted = false` property that I added to all my task objects in their initial state. How this works is a `Todo` component is created with the `completedToDo` function. This function has access to the `index` attribute. My `ToDo` component now looks like:

```js
const Todo = ({ todo, index, completedToDo }) => {
  // Set variabls to hold me strings here
  const complete = "Complete";
  const undo = "Undo";
  
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completedToDo(index)}>
          {" "}
          {todo.isCompleted ? undo : complete}
        </button>
      </div>
    </div>
  );
};
export default Todo;
```
You can see that I have an onClick even handler that registers when I click a task button, and sends the index up to my `completedToDo` function. Depending on whether `todo.isCompleted` if flase or true I display different text. Not a huge change, but it makes it feel more like a task list. It's in my `completedToDo` function where I'm changing my boolean value. And then I'm using my react hook variable, `setTodos`, to update my react hook state. 

```js
newTodos[index].isCompleted === false
      ? (newTodos[index].isCompleted = true)
      : (newTodos[index].isCompleted = false);
setTodos(newTodos);
```
So that's mainly it! Now we have buttons that can be marked as completed, or if we accidentally hit it or realize there was something missing, we can always `undo`.

![crossed out text](https://dev-to-uploads.s3.amazonaws.com/i/jcbly0tmvk4o2onm2bvb.png)

4) __Question:__ How can I delete an item from my list?

Well it's basically a lot like the function I created to mark a task as completed.

```js
  const removeTodo = index => {
    // create a copy of original array
    const newTodos = [...todos];
    // use splice() to remove item from array based on it's index
    // alters that copy of the array that we've made
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };
```

__Answer:__ We add this callback at a prop in our `ToDo` component, it grabs the index, I create a copy of my `todos` array, use the `splice()` method to remove an element from our array based on it's  index. Then the new array copy with remove elements is set with `setTodos`.

And that's pretty much it! Now both you and I understand the basic of using the `usState` React Hook to add state to your functional components.

![Final List](https://dev-to-uploads.s3.amazonaws.com/i/lnmc1kd5hs8o30ux93zh.png)

# Conclusion

[Scotch.io](https://scotch.io/tutorials/build-a-react-to-do-app-with-react-hooks-no-class-components) has some great tutorials, sometimes they can be outdated, but for the most part it's a great resource to have. Again, I didn't create this project, but wanted to talk through the parts I need to take a second to research. As you saw, hooks aren't that scary once you jump in! And a big thanks to [Sarah Chima](https://dev.to/sarah_chima), follow her for some more cool walk-troughs and tutorials!

Oh and if you want to take a look at the coded version, I added a link to my [CodeSandbox](https://codesandbox.io) I created. I also advise using that or [CodePen](https://codepen.io), since with the free version you can create an infinite amount of public projects that can be fairly compartmentalized with different files/ NPM packages.

[![Edit react-hooks-useState-intro](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/relaxed-keller-ddljg?fontsize=14&hidenavigation=1&theme=dark)