React essentially has two types of components that can be created: class components and function components. Features such as state, lifecycle, and others can only be applied to class components and are not possible to implement in function components. However, since React v16.8.0, function components can perform many tasks that were traditionally exclusive to class components with the help of Hooks.
Hooks are special functions that can be applied within function components to access various features provided by React. While in class components, we use methods like componentDidMount
and others to access lifecycles, in function components, we can use Hooks to access the lifecycle of a component. Hooks are typically named with the prefix "use."
There are several built-in Hooks provided by React, including:
- useState
- useEffect
- useRef
- useMemo
- useCallback
- useContext
Rules When Using Hooks
There are some rules that must be followed when using Hooks to avoid unwanted issues.
Hooks can only be used inside function components or custom hooks that we create ourselves. Hooks cannot be applied inside functions in general or class components.
Hooks can only be used at the top level within function components. Therefore, Hooks should not be placed inside conditional statements, loop statements, or nested functions. By adhering to this rule, you ensure that Hooks are called in the same order every time the component is rendered, allowing React to maintain the state of Hooks when useState
and useEffect
are called.
import { useState } from 'react';
const Menu = ({ title }) => {
// Hooks are applied at the top level like this
const [theme, setTheme] = useState('light');
if (true) {
// This is not allowed
// Because it is applied inside a conditional statement
const [value1, setValue1] = useState("Tekken");
}
const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark');
// This is not allowed
// Because it is applied inside a nested function
const [value2, setValue2] = useState("Final Fantasy");
while (true) {
// This is not allowed
// Because it is applied inside a loop statement
const [value3, setValue3] = useState("Monster Hunter");
}
};
// This is allowed, as it is still at the top level.
const [value4, setValue4] = useState("Fire Emblem");
if (!title) {
return null
}
// This is not allowed
// Because it is applied inside a conditional statement
const [value5, setValue5] = useState("Persona");
return (
<div>
<h1>{title}</h1>
<button
style={{ backgroundColor: theme === 'dark' ? 'black' : 'white' }}
type="button"
onClick={toggleTheme}
>
Toggle Theme
</button>
</div>
);
};
export default Menu;
The above rules must be followed because React relies on the order in which Hooks are called every time a component is rendered.
Conclusion
By understanding what Hooks are, you can use various essential features that React provides directly from within function components. Additionally, adhering to the rules of using Hooks is essential to avoid unintended bugs.