- Published on
Most Popular React Hooks Explained with Examples
- Authors
- Name
I wanted to explain the most popular React hooks in short sentences and with examples. Both to help you guys with understanding React, but also to refresh my knowledge.
1. useState
Creates an “state variable” which updates the component on change.
useState is the most common hook in React. The hook needs 3 inputs to create a state.
- Current state (count): The name of the variable, which is equal to the current state.
- Function (setCount): A function which gets called to change the state.
- Initial value (0): The default value when page initialised.
import { useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Add 1 to count</button>
</div>
);
};
2. useEffect
A function which gets called every time the view gets mounted, or when the state inside [] changes.
useEffect is very often used in React. One of the key things to notice when using useEffect, is the second param: []. Their is a big difference between leaving the squared brackets empty, or entering a state(s).
- Empty []: This means that the useEffect() only gets called once upon mounting.
- Filled [count]: This means that the useEffect() gets called on mounting, and when the state (count) changes.
import { useEffect, useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("View Mounted");
}, []);
useEffect(() => {
console.log("View Mounted or Count updated");
}, [count]);
// .. //
};
3. useRef
A hook which can store a mutable value, which does not re-render the view on update.
Also, it can be used to store DOM elements.
The most common use of useRef, is to store an element, which then can be accessed within the component. This can be useful when creating a input field, where you e.g. need to access the value.
import { useRef } from "react";
const App = () => {
const inputRef = useRef();
return (
<input
ref={inputRef}
onChange={() => {
console.log(inputRef.current.value);
}}
/>
);
};
4. useMemo
A function which only gets called every time an specific state changes.
useMemo works very similar to useEffect, since it only gets called every time the state within the squared brackets changes. This can be useful when calling an API, which shouldn’t be called every time the component refreshes.
import { useState, useMemo } from "react";
const App = () => {
const [apiURL, setApiURL] = useState("https://callAPI/");
const apiResults = useMemo(() => {
callAPI();
}, [apiURL]);
return (
<div>
<button onClick={() => setApiURL("https://dummyAPI")}>Change API Url</button>
</div>
);
};
const callAPI = () => {
console.log("Call API");
};
5. useCallback
Works exactly like useMemo, but instead of returning a value, it returns a function.
useCallback works exactly the same as useMemo. However instead of calling the function when the state changes, it sets up a function which then becomes callable.
This can be useful when needing to pass props into the function.
// Returns the value 100
const apiResults = useMemo(() => {
return 100
}, [apiURL]);
// Returns a function, which then can be called
const getApiResults = useCallback((value) => {
return 100 + value
}, [apiURL]);
6. useContext
Creates a state which is accessible from all components.
In this example we are looking at how to share a state variable among two components, which declares if the application is dark themed.
Normally you would have to pass this information through props, but this would be very painfull when working with multiple components.
Therefore we can use useContext, which creates an state variable, which can be accessed from all components, without the need for props.
// App.jsx //
import { useState, createContext } from "react";
export const ThemeContext = createContext(null);
const App = () => {
const [isDarkThemed, setIsDarkThemed] = useState(false);
return (
<ThemeContext.Provider value={isDarkThemed}>
<button onClick={() => setIsDarkThemed((prev) => !prev)}>
Change Theme
</button>
<AboutPage />
</ThemeContext.Provider>
);
};
export default App;
We can then fetch the isDarkThemed value in AboutPage.jsx
// AboutPage.jsx //
import { useContext } from "react";
import { ThemeContext } from "./App";
const AboutPage = () => {
const isDarkTheme = useContext(ThemeContext);
return (
<div style={{ backgroundColor: isDarkTheme ? "black" : "white" }}>
// .. //
</div>
);
};
7. useReducer
Works similar to useState, but instead of having a single value, it contains an object.
Difference between useState and useReducer:
- useState can only store one value, e.g. “0”.
- useReducer can store an object, which can have multiple values. Also, it contains the dispatch function, which simplifies more advanced functionality.
useReducer should be used when you have an object, which has multiple state values. E.g. when storing an user object, which has a name, email and _number.
_Then it is simpler to have 1 useReducer, compared to 3 useState’s for each user values.
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
const App = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: "increment" })}>Increase</button>
<button onClick={() => dispatch({ type: "decrement" })}>Decrease</button>
</div>
);
};
8. useLayoutEffect
Works similar to useEffect, but instead gets called before view gets mounted.
Difference between useEffect and useLayoutEffect:
- useEffect gets called when the view appears or mounted.
- useLayoutEffect gets called before the view appears or mounted.
This can be useful when needing to show list of items instantly upon screen display, without it causing a small blink/flash.
Warning: React official docs say: “useLayoutEffect can hurt performance. Prefer useEffect when possible.”
import { useLayoutEffect} from "react";
const App = () => {
useLayoutEffect(() => {
console.log("View has not mounted yet");
}, []);
// .. //
};
That's it for this topic. Thank you for reading!