Introduction
React Hooks are a great tool for all React developers, but especially for beginners and intermediate developers. They are one of the main tools for improving the readability, reusability and maintainability of your code.
Think about it: it’s like replacing conventional building blocks with custom-made ones that make your application more stable and organized. And that’s what React Hooks can do for you!
What are React Hooks and why are they useful?
React Hooks were created to make life easier when it comes to managing state and side effects in React’s functional components. The idea was to simplify and make our code cleaner, easier to read, reuse and maintain.
Before Hooks, the thing was using class components, which were kind of like a puzzle – you could solve it, but it was sometimes a bit of a pain, especially when you had a lot of pieces. It was like looking for a needle in a haystack of code.
For example, do you want a counter that increments when you click a button? Super easy with useState
. And when you want something to happen whenever that counter changes, just use useEffect
. Take a look at the difference between doing this with React Hooks and class components.
// No reaction hooks
class Contador extends React.Component {
state = {
count: 0,
}
componentDidMount() {
document.title = `Count: ${this.state.count}`
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
document.title = `Count: ${this.state.count}`
}
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>Increment</button>
</div>
)
}
}
// Com React Hooks
function Counter() {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = `Count: ${count}`
}, [count])
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
React Hooks, especially useState
and useEffect
, are like a toolbox that makes your React development experience much more productive. They encourage you to write more organized and reusable code, resulting in cleaner and more maintainable applications.
Oh, and React Hooks also include useRef
, useContext
, useReducer
and a few others. Check out the full list . These hooks can be used to manage state, do some tricks with side effects, and access context data in a variety of ways.
1. Use useStateonly to manage state that is essential to your component
is useState
a powerful React Hook that lets you control state in your functional components. You can use it to keep track of anything that changes over time, like the value of a form field, the score in a game, or the list of items in your shopping cart.
Every time you use useState
, you are creating a new state variable. This can accumulate and make your components slow and difficult to understand, so know how to use it correctly, creating only essential states for your component.
Do:
import React, { useState } from 'react';
const Count = () => {
const [counter, setCount] = useState(0); // State essential: contador
const handleIncrement = () => {
setCount(prevContador => prevContador + 1);
};
return (
<div>
<p>Count: {counter}</p>
<button onClick={handleIncrement}>Increment</button>
</div>
);
};
export default Count;
Here we are using it useState
to manage the essential state (counter) that is needed by the component, which is the right way.
Keeping only essential state in your component helps keep your code organized and easy to maintain. It also makes it easier to understand how your component works and how it changes over time.
Don’t do:
import React, { useState } from 'react';
const PerfilUsuario = () => {
const [loggedIn, setLoggedIn] = useState(false); // State don't essential: logged in
const handleLogin = () => {
setLoggedIn(true);
};
const handleLogout = () => {
setLoggedIn(false);
};
return (
<div>
<p>User is logged in: {logado ? 'Yes' : 'No'}</p>
<button onClick={handleLogin}>To enter</button>
<button onClick={handleLogout}>To go out</button>
</div>
);
};
In this component, the state logado
using React Hooks is considered non-essential because it is not directly related to the main functionality or purpose of the component UserProfile
. The purpose of this component is to display the user profile information, the main focus is not to manage the user’s login status.
Be careful about using non-essential states in your React Hooks component, as this can make your code complicated and difficult to read. It can also cause performance issues, especially when you have a large number of states.
2. Use useStateto control an immutable state
Think of a state as something that cannot be changed directly. This means that you should never directly change the state variable. Instead, whenever you want to make a change, you create a new copy of that variable. This helps maintain the reliability of your data and prevents unexpected changes, ensuring that your program works as expected.
Do:
import React, { useState } from 'react';
const ContadorImmutable = () => {
const [counter, setCounter] = useState(0); // Immutable state: counter
const handleIncrement = () => {
// Update the counter immutably using the setCounter function
setCounter(prevCounter => prevCounter + 1);
};
return (
<div>
<p>Count: {counter}</p>
<button onClick={handleIncrement}>Increment</button>
</div>
);
};
export default ContadorImmutable;
In this example, we are using the setContador
to update the counter that should not be changed directly. This follows React’s rules, making everything more organized and reliable. Keeping the states immutable also makes it easier to understand and find errors in your code.
Don’t Do:
const ContadorMutable = () => {
const [counter, setCounter] = useState(0);
useEffect(() => {
setCounter(counter + 1);
});
return (
<div>
<p>Count: {counter}</p>
</div>
);
};
The reason it is not correct to update state variables directly in useEffect
, for example, is because this can generate infinite loops.
In this example, the useEffect
will be triggered after each render, and it will increment the state variable count (counter), this means that the state variable will be incremented continuously, creating an infinite loop.
3. Use useState pra organizar teu estado de uma maneira normalizada
This means that you should organize the state(s) in a standardized and organized way. Instead of piling all the data into one pile, divide it into smaller, well-organized pieces. Each piece of data has its own unique identifier, which makes it easier to find, update, or work with it.
Do:
import React, { useState } from 'react';
const StandardizedProducts = () => {
const [products, setProducts] = useState({
1: { id: 1, name: 'Product A' },
2: { id: 2, name: 'Product B' }
}); // Estado normalizado: produtos
return (
<div>
<ul>
{Object.values(products).map(product => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</div>
);
};
export default StandardizedProducts;
An example of how to use useState
and keep our data organized. Each product has its own special ID, which makes it easy to find and edit them. This way, we can search for our products and make changes when necessary. It’s like having a well-organized toolbox where each tool has its place – you can quickly find the right tool.
Don’t Do:
import React, { useState } from 'react';
const StandardizedProducts = () => {
const [prodycts, setProduct] = useState([
{ id: 1, name: 'Produto A' },
{ id: 2, name: 'Produto B' }
]); // Estado não normalizado: produtos
return (
<div>
<ul>
{products.map(product => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</div>
);
};
export default StandardizedProducts;
A “denormalized” state using React Hooks means that the data is not organized efficiently. In this example, we are using useState to manage a list of products as well, but here each product is represented as an object inside an array and there is no identifier for that product.
If you have a lot of products in your list, using a disorganized state with React Hooks can make it difficult to find and update specific products. It can also cause performance issues, especially if you’re displaying a list of all your products.
Conclusion
React Hooks, like useState
and useEffect
, are powerful tools that can make your code more modular, reusable, clean, and maintainable.
Use useState
to manage the component’s essential state, ensuring immutability and normalization. Use useEffect
to handle side effects such as data fetching and subscriptions.
By following these principles, you can achieve a new level of efficiency and elegance in your React development journey.
Good hooks! 🚀
Deixe um comentário