loading...
Cover image for State usage in Functional and Class Components in React

State usage in Functional and Class Components in React

chilupa profile image Pavan Chilukuri Updated on ・3 min read

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.

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

 <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.

 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.

  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,

let newCopiedArray = [...this.state.todos];

is same as

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 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.

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.

const [todo, setTodo] = useState("");

This is Javascript Array Destructuring 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.

  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, 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.

  const handleTodoChange = event => {
    setTodo(event.target.value);
  };

Instead of this.setState({ todo: event.target.value }); now it is simply setTodo(event.target.value);

Similarly,

  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 and Functional based approach. Thank you for your time. I hope you enjoyed reading this post. Feel free to write your comments or questions if any.

Posted on Dec 10 '19 by:

chilupa profile

Pavan Chilukuri

@chilupa

Full Stack Developer 💻 Photographer 📷

Discussion

markdown guide
 

Hi! Nice article!

Small tip:
to add syntax highlight — just add js or jsx to your code snippets opening backticks.
e.g. '''jsx (with backticks intstead of ')

--

Also, you might not need a state! Check out my experiment with JSX and RxJS:

<div>{
  axios(url).then(r => r.data)
}</div>
 

Thank you for the suggestion, I've edited my post. 👍