Introduction to React Hooks

The ultimate guide in using React Hooks

Himali Marasinghe
The Startup
8 min readMar 31, 2020

--

React Hooks are a new addition in React 16.8. They let you use state and other React features in functional components. So in this article we are just going to touch mostly used hooks in React.

In the longer term, we expect Hooks to be the primary way people write React components — React Team

State Hook — useState

useState lets you use local state within a function component.

  1. Declare state variable

We can declare a state by simply calling useState method with initial value.

2. Update state variable

We can update the state variable by invoking updater function returned by useState invocation.

3. useState can be used multiple times within a single functional component.

4. useState can accept primitive value or object as the initial value passed on to useState function

5. It is also possible to initialize a state by supplying a function as an argument to useState(computeInitialState)

6. If you need to update the state based on the previous state, supply a callback function setState(prevState => newState).

Effect hook — useEffect

useEffects accept a function which can perform any side effect. So what are side effects?

There are two kinds of side effects:

  1. Effects that do not require cleanup: Network requests, manual DOM mutations, and logging
  2. Effects that do require cleanup: Subscription to external data

Functional components don’t have lifecycle methods. Hence, with useEffect componentDidMount, componentDidUpdate and componentWillUnmount lifecycle methods are unified into a single API.

useEffect syntax

  1. You can clean-up function, by simply returning a function from within the effect function passed to useEffect. The clean-up function is called when the component is unmounted.

2. You can have multiple useEffect hooks within a functional component.

React invokes effect hook on every single render.

3. You can avoid useEffect calls to be invoked by every single render by passing an optional second array argument to the effect function. Then the effect will only re-run if any of the values in array changes.

The above code ensures that we only make fetch requests on mount and when we get a new index.

4. You can run effect hook only once (when a component is mounted) by passing an empty array as the second argument.

Callback hook — useCallback

useCallback hook returns a memoized or a cached version of callback, which improves the performance of the component. useCallback hook is useful when passing callback from parent to optimized child component that rely on referential equality to prevent unnecessary re-renders of child component. ( e.g. shouldComponentUpdate). useCallback re-runs only when one of it’s dependencies changes.

In the below example Dropdown component will always receive the same callback for handleItemClick until there’s a change in data or onClick elements.

Every value referenced in the callback should also appear in the array of dependencies. The exhaustive-deps rule in eslint-plugin-react-hooks package warns when dependencies are specified incorrectly and suggests a fix.

Memo hook — useMemo

useMemo is very similar to useCallback, but it returns a memoized value that is the result of the function parameter instead of a memoized callback. useMemo is especially useful for expensive operations like transforming API data or doing expensive calculations that you don’t want to be re-doing unnecessarily.

In the below example, we will prevent re-calculating of filtered list each time ListContainer component is rendered until the “items” property changes.

Refs hook — useRef

In functional components useRef hook allow us to easily use React refs. This is similar to the createRef in class components. The difference is createRef will return a new ref on every render while useRef will return the same ref each time. Refs provide a way to access DOM nodes or React elements created in the render method and for keeping mutable variable (like instance variables in class components).

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

  1. Accessing DOM nodes or React Elements

The below example manages the focus on text input when user clicks on the button.

2. Keeping a mutable variable

To keep data between re-renders, functional components can use “refs”, which can hold any value. Mutating the .current property will not trigger a re-render.

In the below example stringVal object hold a reference to a string value,

Context Hook — useContext

useContext hook helps to avoid creating multiple duplicate props. This specially comes in handy if you need to pass props from parent component down to multiple level of child components.

In the below example we’re passing down user prop down to two levels,

Now, we can refactor the above code using useContext hook.

Reducer hook — useReducer

useReducer hook is another way of handling state. When an event changes multiple states together (eg. isFetching, fetchedData) or the next state depends on previous state ( eg. todos) useReducer hook can be used.

reducer — is a callback function.

initialState — is the initial value.

dispatch — is an alias for action in our reducer

state — is the current state

By this way, when an action is triggered we can find all the logic related to state update in a single place.

Custom Hooks

Aside from the hooks that React has provided, we can write our own hooks to meet with our project’s requirements.

In the below example, we create a useFetch hook to fetch data from an API, which returns loading and data props.

One thing to keep in mind is to start hook’s name with word “use”.

We provide an ESLint plugin that enforces rules of Hooks to avoid bugs. It assumes that any function starting with ”use” and a capital letter right after it is a Hook.

Rules of Hooks

There are two core rules of using react hooks,

  1. Only call hooks at the top level

Don’t call hooks inside loops, conditions, or nested functions. This ensures that hooks are called in the same order each time a component renders, which is necessary for hooks to work.

2. Don’t call hooks in normal javascript functions or in class components.

  • Call hooks from React functional components.
  • Call hooks from custom hooks

Use eslint-plugin-react-hooks that enforce these two rules.

Thanks for reading the post! I hope this article has been helpful for you to understand the basics of React Hooks and its usage. Please feel free to comment, share and ask questions.

--

--