Today we'll learn about the widely used hooks in React. First, let me tell you the need for hooks. As we all know React has functional and class components. Previously, the functional components were only used to render the data but didn't consist of the business logic or any side effect in itself.
So hooks were introduced to implement lifecycle methods and states in functional components. They also bought the idea of code reusability along with them, that's why it was so quickly accepted within the React Community.
** Drum rolls 🥁 **
Let's move ahead with the main topic.
- useState hook
This hook helps us to use and maintain a state within the functional component. It's very easy to use. The useState hook returns an array having two elements, the first one is the state variable and the second is the function that modifies the state variable.
import { useState } from "react";
export default function App() {
const [number, setNumber] = useState(0);
return (
<div className="App">
<button onClick={() => setNumber(number - 1)}>Subtract</button>
<input
type="number"
value={number}
onChange={(e) => setNumber(e.target.value)}
/>
<button onClick={() => setNumber(number + 1)}>Add</button>
</div>
);
}
Here, we have number
as the state variable and setNumber
as the function which will modify the number
.
- useEffect hook
This hook works as a replacement for all the lifecycle methods which were used in class components. It contains a callback and a dependencies array. The hook will run every time when any of the values in the dependencies array changes.
import { useEffect, useState } from "react";
export default function App() {
const [number, setNumber] = useState(0);
const [isEven, toggleEven] = useState(true);
useEffect(() => {
if (number % 2 !== 0) {
toggleEven(false);
} else {
toggleEven(true);
}
}, [number]);
return (
<div className="App">
<button onClick={() => setNumber(number - 1)}>Subtract</button>
<input
type="number"
value={number}
onChange={(e) => setNumber(e.target.value)}
/>
<button onClick={() => setNumber(number + 1)}>Add</button>
<p>{isEven ? "Even" : "Odd"}</p>
</div>
);
}
Here as you can see, the dependencies array contains number
. So every time the user presses any of the buttons or changes the input value, the useEffect
hook will trigger and it'll check the number whether it's odd or even.
Within this hook, you can call side effects such as changing something in DOM, fetching data from an API, etc.
One more thing used in this hook is the cleanup function, which runs when we return a function in the callback. This function helps in cleaning of side effects i.e clearing a timer, closing a web socket, etc.
- useContext hook
As in the class components, we had the Context API in the same way, we have useContext
hook in functional components. This hook basically helps you to maintain a common global state across components. When the state changes it triggers re-renders across all the child components under the Context, even if the parent component uses shouldComponentUpdate
or React.memo
.
This hook can be used to implement a loading state within the application, passing data to children components, etc.
To create it, we use the createContext
function and pass the initial value. In the context provider, we pass a prop called value
which consists of the context variables and functions to modify the context.
import { createContext } from "react";
export const UserContext = createContext({
name: "Initial Name"
});
Then we use this context in our Parent Component and wrap our app inside the Context Provider and pass a value. So now all the child components have the access to the value
prop.
import { useContext, useState } from "react";
import Person from "./Person";
import { UserContext } from "./Context";
export default function App() {
const user = useContext(UserContext);
const [person, togglePerson] = useState(user);
return (
<UserContext.Provider value={[person, togglePerson]}>
<div className="App">Hello {user.name}!</div>
<Person />
</UserContext.Provider>
);
}
Now in the child component Person
we can access the value
prop and we can change the context value too.
import { useContext } from "react";
import { UserContext } from "./Context";
function Person() {
const [person, togglePerson] = useContext(UserContext);
return (
<div>
Person: {person.name}
<button
onClick={() => {
togglePerson({ name: "Stuart Little" });
}}
>
Change
</button>
</div>
);
}
export default Person;
This way you can use the useContext
hook. Make a context, wrap the parent component with the context's provider and you are good to go!
You can experiment with the above code here.
- useReducer hook
If you know Redux then you already know what this hook does, if not then simply it changes the state
according to the action
passed. It helps in maintaining a local state easily whereas in Redux we can do that globally.
To use the reducer globally, we can make a context and pass it across the components. Geddit!
Here we have an initial state and a dispatch to modify the state. Within the dispatch, we pass actions along with some info called payload
. The action then goes to the reducer which in turn changes the state.
import { useReducer } from "react";
import "./styles.css";
const initialState = [
{
name: "Mad Angles",
quantity: 5
},
{
name: "Pringles",
quantity: 3
},
{
name: "Lays",
quantity: 2
},
{
name: "Kurkure",
quantity: 1
},
{
name: "Uncle Chips",
quantity: 9
}
];
function reducer(state, action) {
switch (action.type) {
case "add":
return [...state, action.payload];
case "delete":
return state.filter((_, index) => index !== action.payload);
default:
return state;
}
}
export default function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<ul>
{state.map(({ name, quantity }, index) => (
<div className="list-item">
<li key={name}>
<b>{name}</b> - {quantity}
</li>
<button
onClick={() => {
dispatch({ type: "delete", payload: index });
}}
>
delete
</button>
</div>
))}
<button
onClick={() => {
dispatch({
type: "add",
payload: {
name: "Doritoes",
quantity: 5
}
});
}}
>
add
</button>
</ul>
</div>
);
}
You can find the above code here.
That's it for now. There are other hooks too like useRef
, useCallback
but they are rarely used. Thanks for reading this article. Let me know if anything is not clear.
Happy Coding!
Top comments (0)