State usage in Functional and Class Components in React
Tags: react, javascript, beginners, webdev
Published: 2019-12-10 08:25:57

I created a __Todo app__ with two approaches namely - _class based_ and _functional based_ approach. The purpose of this article is to compare these both approaches and help you understand the react hooks in functional components, managing state in both _class_ components and _functional_ components.

### Class based approach
This is pretty much straight! Create an ES6 class, define its constructor. Declare the _state_ variable in the constructor and assign initial values to it.
```jsx
export default class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      todo: "",
      todos: [
        { name: "Buy groceries", done: false },
        { name: "Pay rent", done: false }
      ]
    };
  }
}
```

I created an other component `Input`, which takes the input value from user (a `todo`). It accepts a _prop_ named `changed` and we are assigning the value returned by the ES6 function, `handleTodoChange` to the prop `changed`

```jsx
 <Input changed={handleTodoChange} />
```

Coming to the `handleTodoChange` function, it takes one argument, `event` and it looks for the change in the input field. Whatever the user types, the change is recorded and updated constantly to the `todo` state variable.

```jsx
 handleTodoChange = event => {
    this.setState({ todo: event.target.value });
  };
```

When user hits on Save button, a `todo` should appear the in the list of Todos. For this, we will handle the save button function as below.
```jsx
  handleSave = todo => {
    let newCopiedArray = [...this.state.todos];
    newCopiedArray.push({ name: this.state.todo, done: false });
    this.setState({ todos: newCopiedArray });
  };
```

Instead of the ES6's spread operator (`...`), you can also use javascript `slice()` method. It is one and the same.
For instance, 
```js
let newCopiedArray = [...this.state.todos];
```
_is same as_
```js
let newCopiedArray = this.state.todos.slice();
```

### Functional based approach

With the advent of __Hooks__, we can manage the `State` right in our functional components. No more converting the functional components to class components! `useState()`, `useEffect()` are few examples of React Hooks. We will be using `useState()` for now.

### Wondering what a "Hook" is?
> [Hooks](https://reactjs.org/docs/hooks-state.html#whats-a-hook) are functions that let you “hook into” React state and lifecycle features from function components.

Keep in mind, _Hooks_ __don’t work__ inside _classes_. They let you use React __without__ classes.

Let us re write the `Todo` Component as a function and declare the state variables just like we did in the `class` component.
```jsx
const Todo = () => {
  const [todo, setTodo] = useState("");
  const [todos, setTodos] = useState([
    { name: "Buy groceries", done: false },
    { name: "Pay rent", done: false }
  ]);
}

```
If you observe, this is a functional component and with the use of hook, `useState()` the code looks much clean. Isn't it? Don't worry about the syntax, I'm going to break it down for you going further.
```js
const [todo, setTodo] = useState("");
```
This is Javascript [Array Destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) concept. From the above line of code, we are creating two new variables `todo` and `setTodo`, where `todo` is set to the first value returned by useState, and `setTodo` is the second. It is same as the code below.
```js
  let todoStateVariable = useState(''); // Returns a pair
  let todo = todoStateVariable[0]; // First item in a pair
  let setTodo = todoStateVariable[1]; // Second item in a pair
```
Here's a bonus from React Docs
> When we declare a state variable with [useState](https://reactjs.org/docs/hooks-state.html#tip-what-do-square-brackets-mean), it returns a pair — an array with two items. The first item is the current value, and the second is a function that lets us update it. Using `[0]` and `[1]` to access them is a bit confusing because they have a specific meaning. This is why we use array destructuring instead.

Let's change the `handleTodoChange` and `handleSave` functions using state variables.
```jsx
  const handleTodoChange = event => {
    setTodo(event.target.value);
  };
```
Instead of `this.setState({ todo: event.target.value });` now it is simply `setTodo(event.target.value);`

Similarly, 

```jsx
  const handleSave = todo => {
    let newCopiedArray = [...todos];
    newCopiedArray.push({ name: todo, done: false });
    setTodos(newCopiedArray);
  };
```

That is it! You have seen both the approaches and use of hooks in the functional components.

---

You can checkout the source code here for [Class based approach](https://github.com/chilupa/todo-app-react/tree/master/src) and [Functional based approach](https://github.com/chilupa/todo-app-react/tree/02-react-hooks/src). Thank you for your time. I hope you enjoyed reading this post. Feel free to write your comments or questions if any.