Understanding React Hooks
JerryMcDonald
Posted on July 6, 2020
React Hooks are a feature that is new to react since the React 16.8 update. They give you the ability to use state features without creating a class constructor. Hooks allow developers to break up complex class constructors even further. Developers wanted an easier way to break down substantial class components, extract stateful components to function or another element, and cut down on intricate patterns like props and higher-order components. Hooks solved the problem of React functions not having "state" in them.
According to the React documentation on hooks, the company has no plans to eliminate the class component. The React team would like developers to gradually adapt hooks and combine the knowledge with React skills they already know. I am going to talk about some hooks you should know to get started. But before we do, let us look at some of the rules you need to follow while using hooks.
Rules of hooks
You only want to call hooks at the top level of your function. Do not use
useState
in a loop, conditional, or nested function. Because for React to keep track of your hooks, they need to be called in the same order each time your functional component runs.You only want to call hooks from React Functional Components. You will need these inside a class component or outside of a component.
When you learn enough to create custom hooks. The names of your hooks must start with 'use.'
Let's take a look at the two hooks you already have access to in your React application. useState
and useEffect.
State Hook
The first hook I will talk about is 'useState,' designed to hold a small-ish amount of data in a function components state. The great thing about 'useState' is that you can assign any data type you would like. You can useState with an array, an object, a number, a string, or a boolean. Each useState call will create a new single piece of state.
Let look at an example of a state variable that I would like to call visible. I would also like to change the value of visible
at any point in my functional component.
// Create a piece of state, and initialize it to `true`
// `visible` will hold the current value of the state,
const [visible, setVisible] = useState(true);
In the above example, we can see that useState is returning an array of two components. A visible
element that will hold the state's value and a setVisible
function that will change the value of the state.
function Profile() {
const [visible, setVisible] = useState(true);
function toggleVisibility() {
setVisible(!visible);
}
But what if we need another way to do the functionality above but by using an updater function. Using prevState
can be useful if you are updating your state inside of a closure. The below example will have the same outcome as above.
function Profile() {
const [visible, setVisible] = useState(true);
function toggleVisibility() {
setVisible(prevState => !prevState);
}
We can also save arrays and objects to our state.
// array example
const [someArray, setSomeArray] = React.useState([]);
setSomeArray(prevState => [...prevState, 'newdata'] );
You can see here when we are setting a new value to the state array; we utilize the ES6 spread operator to concatenate the prevState
array with our new data.
Let's look at setting an object to state and using the spread operator to update it.
function Profile() {
const [user, setUser] = useState({
username: '',
profileImgUrl: ''
});
const updateUrl = url => {
setUser({
...user,
profileImgUrl: url
});
};
An important thing to remember is that you cannot update a state by reassigning the state name. Suppose you find yourself having a nested array or object and having trouble using the spread operator, concat, and update a single element in your object. You do a trick that I like to use and create a new object before updating the state.
function Profile() {
const [user, setUser] = useState({
username: '',
password: '',
pets: ['Ms.Mittens', 'JoJo'],
}
const addAPet = petName => {
// make a copy of the user
const userCopy = { ...user }
// now you can make changes to the copy
userCopy.pets.push(petName);
// then you can set the state to the new object
setUser(userCopy);
};
Learning the trick can come in handy when your objects become a bit more complicated and you can't get the spread operator to work quite right.
Effect Hook
The Effect hook useEffect
allows the developer to perform side effects from a functional component. These side effects can include but are not limited to data fetching and subscriptions.
The useEffect
hook can be considered a componentDidMount
or a componentDidUpdate
from a class component.
function MemberPage() {
const [memberCount, setMemberCount] = useState(0);
useEffect(() => {
// Update the document title using the browser API
document.title = `You have ${memberCount} members`;
});
return (
<div>
<p>You have ${memberCount} members</p>
<button onClick={() => setMemberCount(prevState => prevState + 1)}>
Add a member
</button>
</div>
By default, React is running the useEffect each render, including the first render, making the useEffect useful for a fetch request at the beginning of your components life cycle.
useEffect(() => {
fetch(
`https://api.github.com...`,
{
method: "GET",
headers: ..."
})
}
)
.then(res => res.json())
.catch(error => console.log(error));
});
Using the useEffect
Hook will allow you to affect other components and do important data collection that cannot be done during rendering.
Using Hooks can allow you to separate your class components even further, which will make your code easier to read and debug. If you are new to using hooks and would like to learn more about them (or even how to create hooks), I put some excellent resources down below.
Resources:
Posted on July 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024