React Hooks

useState

Until now we haven't used state except in Class Components. In order to use state in Functional Components we need some sort of hooks called useState.

Hooks are new addition in React version 16.8. They let you use state and other React features without writing a class. Hooks are the functions which "hook into" React state and lifecycle features from function components. It does not work inside classes.

We use destructuring to write a state using useState hook

const [ count, setCount ] = useState(0)
  • We declared two constants one is called count, the other is called setCount from the value returned from calling useState

  • The value of the count constant is the value of the argument useState is called with which is 0 here.

  • setCount is a function to set the count state to a new value whenever called, for example setCount(100) which sets the count state to 100.

Do you remember this component πŸ‘‡

import React, { Component } from 'react';

class App extends Component {
  state = {
      count: 0,
  }

  countUp = () => {
    this.setState({
      count: this.state.count + 1,
    });
  }

  resetCount = () => {
    this.setState({
      count: 0
    });
  }

  render() {
    const { count } = this.state;
    return (
      <div>
        <button onClick={this.countUp}>Increase Count</button>
        <button onClick={this.resetCount}>Reset Count</button>
        <p>{count}</p>
      </div>
    );
  }
}

export default App;

Let's convert it to a functional component and keep using a state via useState

πŸ€” Changes happened:

  • We don't have to import Component from react.

  • We have to import useState to be a stateful functional component.

  • We can make App it a regular function component, function expression, or an arrow function.

    • function App() {}

    • const App = function() {}

    • const App = () => {}

  • We used the useState syntax for declare count state and setCount to set the state.

  • We initialized the count state with number value 0. This is the value of count when the component get mounted (app start).

  • Functions inside the component countUp, and resetCount are arrow functions but again we can use any type of function syntax. And when calling them we didn't use this keyword. onClick={CountUp}

  • We omitted the render() method and just returned JSX.

One thing to mention and keep in mind here is that setting the state is an asynchronous task. Additionally, setting the state calls a re-render. That’s the reason we see the new count when clicking the button. If it wouldn’t trigger a re-render then we would still see the old count. Our component will update after setting the state.

Sometimes we want to do some side actions when the state changes. For example in our case here we want to change the background color when the number is odd 1, 3, 7, etc. to blue and keep it white with even numbers. And start the app with a white background. So we need to use lifecycle methods in this scenario πŸ‘‡

componentDidMount: background color = "white" componentDidUpdate: check if number is odd, then background color = "blue". If even number, then background color = "white". This process must repeat with every component update due to count change.

Lifecycle methods can not be used in functional components (the reason is that how React is built behind the scenes and that's it). But there is a much better convenient solution to that. It is useEffect.

useEffect

Recalling the last example, we wanted to change the background color when the number is odd 1, 3, 7, etc. to blue and keep it white with even numbers. And start the app with a white background.

So we need to use lifecycle methods in this scenario πŸ‘‡

componentDidMount: background color = "white" componentDidUpdate: check if number is odd, then background color = "blue". If even number, then background color = "white". This process must repeat with every component update due to count change.

And as we knew Lifecycle methods can not be used in functional components. Therefore, useEffect comes to the rescue.

Watch this πŸ‘‡

Changes we have made:

  • imported useEffect from react

  • declared a color state and setColor to set the state using useState and initiate it with an initial value of "white" color.

  • called useEffect that takes two arguments.

    • The first argument is a callback function with the action you want to perform.

    • The second argument is a dependency array with the value that useEffect depends on its changes to run the callback function. This means- in our case - that when count state value changes useEffect will run the callback function. This makes it equivalent to componentDidUpdate lifecycle method. But if we left the array empty the hook will run each time there is an update in component and also when the component is initialized (mounted). This makes it equivalent to componentDidMount lifecycle method.

  • Inside the callback function, a condition is made to check if the number in count state number is even or odd. If it is odd, the color state value will be "blue", and in case of even number, the color state value will be "white".

  • In the wrapper div there is a style attribute with the backgroundColor value equals the color state value and changes with its change.

Last updated