React Hooks | Better Functional Components

javascript Nov 10, 2019

React Hooks are one of the most aggressive topic now a days in react community  and i recently i got chance to explore it and believe me it is very easy yest complicated .

In this article we will talk about .

1.)  what are react hooks ?

2.) different  react hooks

3.) and when to use them

What is React Hook

React hooks let you use some different functionalities of  class component (state full components ) in functional components (state-less components) not clear lets see it in action

React hooks are just functions that returns something

lets assume we have one app our old and most commonly used friend the counter app

import React, { Component } from "react";

export default class Example extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  incrementCounter() {
    this.setState(state => {
      return {
        count: state.count + 1
      };
    });
  }
  render() {
    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => this.incrementCounter}>Click me</button>
      </div>
    );
  }
}

a very simple app so simple that ill not explain it 😊

so 3 take aways

  1. above component is statefull class component
  2. it has state with one property count
  3. it uses the setstate function to update the state

so react hooks will let you achive 2,3 point in a functional component with the help of a inbuilt hook that is useState

import React, { useState } from "react";

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

the above functional component will have its own state and can setstate also same like class component

We will see useState and more hooks in more details later

Inbuilt react hooks

  1. useState
  2. useEffect
  3. useContext

useState React hook

as we have seen earlier this hook helps to inject the functionality to manage and have state in functional component .

useState is function part of the core library you import it from React

import React, { useState } from "react";

it is a function which accepts a value which can be anything like an object string or a number and this value is the initial state value or example in class component if i want to to set the count property of state to 0 ill will write it like

export default class Example extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
 }

its exactly the same thing

useState(0)

now this function returns two things one is the state property like count in our example and second is the function to update that state same like setState function

 const [count, setCount] = useState(0);

useEffect React hook

Accepts a function that contains imperative, possibly effectful code.

Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.

Instead, use useEffect. The function passed to useEffect will run after the render is committed to the screen. Think of effects as an escape hatch from React’s purely functional world into the imperative world.

In very simple words giving the componentwillmount, and componentdidupdate lifecycle hook functionality of our functional component

use effect is a function which excepts a function lets say in my counter app i want to set the count value to 10 when the component is mountd ill have some thing like

useEffect(() => {
  setCount(10)
});

Now lets make this example a bit advanced and lets say you want to featch alist of somthing fom the api when component in mount

useEffect(() => {
  props.source.subscribe();
});

so we will have something like this but this code has a problem and the problem is it will become an infinite loop as when ever the component is re rendered the useeffect will be called and it will fetch and then render and then effect will be called and then update and again the hell

so to come out with this problem we can pass one more argument to this useEffect function that is dependency array  which tells react when to call or more descriptively .this effect depends on which properties

useEffect(() => {
  props.source.subscribe();
},[]);

So now if you dont pass anything to the array or pass an empty array this function will only be called once

but lets say your functional component recieves a prop and when that prop changes you want to make a call to api and fetch data in that case

const profile = ({userId}) = >{
    useEffect(() => {
      props.source.subscribe();
    },
    [userId]
   );
}

so you are telling that whenever the userId changes call this function  

last thing is useEffect function returns a function where you can do cleanup stuff and it will be called one the component is removed

useEffect(() => {
  const subscription = props.source.subscribe();
  return () => {
    // Clean up the subscription
    subscription.unsubscribe();
  };
});

Take aways From useEffect

useEffect(() => {
 //do something
  return () => {
    // Clean up the subscription
    subscription.unsubscribe();
  }; // return a function for clean up
},
[] // have controll over effect like when to call them);

useContext React hook

Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest <MyContext.Provider> above the calling component in the tree.

When the nearest <MyContext.Provider> above the component updates, this Hook will trigger a rerender with the latest context value passed to that MyContext provider.

Don’t forget that the argument to useContext must be the context object itself:

  • Correct: useContext(MyContext)
  • Incorrect: useContext(MyContext.Consumer)
  • Incorrect: useContext(MyContext.Provider)

A component calling useContext will always re-render when the context value changes. If re-rendering the component is expensive,

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

Neeraj Dana

Experienced Software Engineer with a demonstrated history of working in the information technology and services industry. Skilled in Angular, React, React-Native, Vue js, Machine Learning