# Hooks

Introduced in React since version 16.8

Official docs (opens new window)

# What are React Hooks?

Hooks are in-built functions that allow React developers to use state and lifecycle methods inside functional components.

React comes bundled with a few Hooks that allow us to manage most of the use cases of the class logic. It also allows us to create custom Hooks whenever we want to reuse component logic.

# 📌 State Hook

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>
	);
}

We know already that useState returns a pair: the current state value and the function that lets you update that value. What react does is to preserve this state between re-renders. It’s similar to this.setState in a class, except it doesn’t merge the old and new state together

# Declaring multiple state variables

function ExampleWithManyStates() {
	// Declare multiple state variables!
	const [age, setAge] = useState(24);
	const [fruit, setFruit] = useState('banana');
	const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
	// ...
}

The (array destructuring)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring] syntax lets us give different names to the state variables we declared by calling useState.

# ⚡️ Effect Hook

You’ve likely performed data fetching, subscriptions, or manually changing the DOM from React components before. We call these operations “side effects” (or “effects” for short) because they can affect other components and can’t be done during rendering.

This hook adds the ability to perform side effects from a function component. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API.

For example, this component sets the document title after React updates the DOM:

import React, { useState, useEffect } from 'react';

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

	// Similar to componentDidMount and componentDidUpdate:
	useEffect(() => {
		// Update the document title using the browser API
		document.title = `You clicked ${count} times`;
	});

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

Effects may also optionally specify how to “clean up” after them by returning a function. For example, this component uses an effect to subscribe to a friend’s online status, and cleans up by unsubscribing from it:

import React, { useState, useEffect } from 'react';

const FriendStatus = (props) => {
	const [isOnline, setIsOnline] = useState(null);

	function handleStatusChange(status) {
		setIsOnline(status.isOnline);
	}

	useEffect(() => {
		ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
		return () => {
			ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
		};
	});

	if (isOnline === null) {
		return 'Loading...';
	}
	return isOnline ? 'Online' : 'Offline';
};

# Dependency Array

As a second argument, useEffect optionally accepts an array of values. Those values will be then compared to the previous values, when deciding if the effect should be ran or not.

It works a bit like shouldComponentUpdate for side effects. If the values changed, the effects will be ran. If none of the values changed, nothing will happen.

function ExampleComponent({ id }) {
	useEffect(() => doSomething(id), [id]);
	return <div></div>;
}

Now, this effect is only executed when id is different from the previous update.