Are you new to React Hooks or would you like to know how to use GreenSock with React?
Then you should definitely understand what React Hooks are and how to use them.
In this React Hooks tutorial will learn:
- What are React Hooks?
- How to manage state using
useState()
- How to fetch data with React Hooks
- How to fix the infinite loop inside of
useEffect()
What are React Hooks?
In short React Hooks let you use state and side effects in a functional components, something what was not possible before.
Before React Hooks were introduced to the world, this would be your workflow:
- create a functional (stateless) component
- realise that you need to manage an internal state of this component
- rewrite this component into a class component
- happily manage components state
Now with React Hooks it looks much more streamlined:
- create a functional component
- happily manage components state
React Hooks let you manage the state and react to state changes in functional components.
You can read more about React Hooks from the official documentation.
Now lets explore the most common state management use cases in React components.
How to manage state with React Hooks?
Imagine that we have a simple React component that needs to be either collapsed or expanded.
import React from 'react'; const Collapsible = () => { return ( <div className="isExpanded"> <h1>Item title</h1> ... </div> ) }
We would need to rewrite this into a class component if there were no React Hooks.
Luckily we have useState
React Hook.
import React, { useState } from 'react'; const Collapsible = () => { const [state, setState] = useState(false); return ( <div className={state ? 'isExpanded' : null}> <h1>Item title</h1> ... </div> ) }
We are importing useState
from React and then creating a default state
with the value of false
.
Then we have access to the state variable
and can render a css class
when required.
If we wanted our component to be expanded by default we would set it to true
by default.
state
and setState
names are customisable names, you could call them whatever you like. color, setColor
or user, setUser
would do the same thing.
You get the point of sticking to a clear naming here.
state
is the name of the stored variable and setState
is a function that updates the value of this variable.
To change the value we could add onClick event to the h1
and toggle the value to the opposite true
or false
.
import React, { useState } from 'react'; const Collapsible = () => { const [state, setState] = useState(false); return ( <div className={state ? 'isExpanded' : null}> <h1 onClick={() => setState(!state)}>Item title</h1> ... </div> ) }
Now we are managing the internal state of our component using the useState
React Hook.
You are not limited to a single value for your state, you can store objects, arrays or even nested objects.
Here is an example of a property
object
being stored in the state.
const [property, setProperty] = useState({ name: 'Hotel Heaven', id: 'hh123', location: 'Collins Street' });
How to fetch data with React Hooks?
Another React Hook that you will need to master is useEffect()
.
It hooks into your React component in the same way as componentDidMount
, componentDidUpdate
, and componentWillUnmount
used to.
Here is an example component that fetches Top board games from Board Game Geek.
import React, { useState, useEffect } from 'react'; const TopGames = () => { const [games, setGames] = useState([]); useEffect(() => { fetch("https://bgg-json.azurewebsites.net/hot") .then(response => response.json()) .then(data => setGames(data)); }); return ( <div> { games.map(game => <p>{game.title}</p>) } </div> ) }
We are importing useEffect
React hook and then inside of it we are:
- fetching
data
from an external API and - saving the response into a local state variable called
games
The problem with the above code is that it would create an infinite loop!
The component mounts, we fetch data, the state gets updated, the components updates, we fetch data…and this continues.
By default useEffect()
runs on the first render and on every update.
How to fix the infinite loop inside of useEffect
To make the fetch call only once, we need to supply an empty array as the second parameter.
useEffect(() => { fetch("https://bgg-json.azurewebsites.net/hot") .then(response => response.json()) .then(data => setGames(data)); }, []);
This empty array tells React to run the function inside of it only after the first render, not on update.
In another example we could include a searchTerm
dependency. This would make sure that the fetch call only happens when the searchTerm
variable is updated.
useEffect(() => { fetch(`https://someurl.com/api/${searchTerm}`) .then(response => response.json()) .then(data => setGames(data)); }, [searchTerm]);
searchTerm
is now a dependency for this side effect and unless searchTerm
is updated, the fetch call would not run.
We have mentioned mount
and update
, but where is the componentWillUnmount()
?
If your effect returns a function, it will be executed when it is a time for the component to be unmounted.
useEffect(() => { // do something here first // then console.log when unmouting return (() => {console.log('unmounting now')}) }, []);
This will simply console.log
every-time this component gets removed from the DOM.
Conclusion
I hope that this article clarified a lot of your questions about React Hooks.
They are a great addition to the React API, make your code more readable and reusable.
I am currently re-recording my React 101 to include React Hooks, join me there to learn more.
Are you struggling with anything related to React Hooks? Have you tried to use GreenSock with React? Let me know in the comments.