The React Hooks you need to know
Learn about useState, useEffect, useRef, and useContext
In this blog, we'll cover fundamental hooks like useState
, useEffect
, useRef
, and useContext
. Then we will talk about custom hooks.
React Hooks
useState
The useState
hook allows functional components to manage state. Let's look at a simple example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
The code initializes a state variable named "count" using React's useState hook.
The initial value of "count" is set to 0.
The "setCount" function is a setter function provided by useState hook, used to update the value of "count" later in the component's lifecycle.
useEffect
useEffect
enables performing side effects in functional components, such as fetching data or subscribing to external events. Here's an illustration:
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState([]);
useEffect(() => {
// Fetch data from an API
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty dependency array triggers effect only once on mount
return (
<div>
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
useRef
useRef
is handy for accessing and interacting with DOM elements directly. Consider the following example:
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef();
useEffect(() => {
// Focus the input element on mount
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}
useContext
The useContext
hook simplifies accessing context values in functional components. Example:
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <p style={{ color: theme }}>Themed Content</p>;
}
Custom Hooks
Custom hooks enable reusing stateful logic across different components. Let's create a simple custom hook for handling form input:
import { useState } from 'react';
function useFormInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
};
return {
value,
onChange: handleChange,
};
}
Now, you can use this custom hook in any component:
import React from 'react';
import useFormInput from './useFormInput';
function Form() {
const username = useFormInput('');
const password = useFormInput('');
return (
<form>
<input type="text" {...username} placeholder="Username" />
<input type="password" {...password} placeholder="Password" />
</form>
);
}
Another custom hook
Let's create a custom hook called useFetch
for handling data fetching using the fetch
API.
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// Usage example in a component
function DataComponent() {
const { data, loading, error } = useFetch('https://api.example.com/data');
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<h1>Data Component</h1>
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
Now, you can reuse the useFetch
hook in any component that needs to fetch data. This promotes code reusability and keeps your components focused on their specific concerns.
Thanks for reading!