Concept Highlights:
- What is Hooks?
- Why Use Hooks?
- useState
- useEffect
- useReducer
- useRef
- Custom Hooks
- Toggle with dispatch
- What is UseHooks.com?
- useCallback
1. What is Hooks and Why
In React, Hooks are special functions that allow you to use state and other React features in functional components, without needing to convert them into class components. Introduced in React 16.8, hooks make it easier to reuse logic between components, handle state management, and manage side effects like data fetching or subscriptions, all within functional components.
2. Why Use Hooks?
- Cleaner Code: Hooks simplify the structure of your components by allowing you to manage state and side effects directly in functional components.
- Reusability: Custom hooks allow you to reuse stateful logic without duplicating code or restructuring components.
- Functional Components: Hooks enable you to write functional components that are just as powerful as class components, leading to a more consistent codebase.
3. useState
The useState
hook is fundamental for managing state in functional components. Instead of using class components with this.setState()
, you can manage state seamlessly with this hook.
Syntax:
const [state, setState] = useState(initialState);
e.g.) In this example, it initializes count
with a value of 0
and use the setCount
function to update it when the button is clicked.
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>
);
}
4. useEffect
The useEffect
hook allows you to handle side effects in your components, like fetching data, updating the DOM, or subscribing to events.
Syntax:
useEffect(() => {
// Side effect logic
return () => {
// Cleanup
};
}, [dependencies]);
e.g.) In this example, useEffect
fetches data from an API when the component mounts. The empty array []
as a second argument ensures the effect runs only once (like componentDidMount
).
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<div>
{data ? <p>{data.title}</p> : <p>Loading...</p>}
</div>
);
}
5. useReducer
When your state logic becomes more complex, consider using useReducer
instead of useState
. It’s similar to Redux but at the component level. You can use it to manage state transitions based on action types.
Syntax:
const [state, dispatch] = useReducer(reducer, initialState);
e.g.) In this example, useReducer
handles two actions: increment and decrement. You use dispatch
to trigger state updates based on these actions.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
6. useRef
The useRef
hook provides a way to directly access and manipulate DOM elements or store mutable values across renders without causing re-renders.
Syntax:
const myRef = useRef(initialValue);
e.g.) In this example, useRef
allows direct access to the input filed, enabling to programmatically focus it when the button is clicked.
import React, { useRef } from 'react';
function InputFocus() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
}
7. Custom Hooks
One of the powerful aspects of hooks is that you can create your custom hooks to encapsulate and reuse logic across components. Custom hooks start with use
and are just regular JavaScript functions that can use other hooks.
e.g.) In this example, the useFetch
hook handles data fetching logic and can be reused in multiple components.
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
function App() {
const { data, loading } = useFetch('https://api.example.com/data');
return <div>{loading ? <p>Loading...</p> : <p>{data.title}</p>}</div>;
}
8. Toggle with dispatch
The dispatch
method can be used in combination with useReducer
to create toggle states, which is helpful for handling components like modals, dropdowns, or toggling themes.
e.g.) The toggle
action in the dispatch
method switches the isVisible
state between true and false, which in turn toggles the visibility of content.
import React, { useReducer } from 'react';
const initialState = { isVisible: false };
function reducer(state, action) {
switch (action.type) {
case 'toggle':
return { isVisible: !state.isVisible };
default:
return state;
}
}
function ToggleComponent() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<button onClick={() => dispatch({ type: 'toggle' })}>
{state.isVisible ? 'Hide' : 'Show'} Details
</button>
{state.isVisible && <p>Here are the details...</p>}
</div>
);
}
9. What is UseHooks.com?
If you're interested in diving deeper into hooks or exploring useful custom hooks for your projects, I highly recommend checking out UseHooks.com. It’s a fantastic resource with tons of practical custom hooks that you can use and learn from.
10. useCallback
The useCallback
hook is used to memorize functions in React. This is especially useful when passing callbacks to child components since it prevents the function from being recreated on every render.
Syntax:
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
e.g.) In this example, the increment
function is memorized using useCallback
, so it's not recreated on every render, which helps improve performance in certain scenarios.
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
Top comments (0)