State & Effects Hooks
State
State is what makes a component “tick”, it’s at the heart of your React component.
Take a look at this Counter
class-based component. It has a simple button and when you give that button a click, it updates the state and the component re-renders.
Notice inside the constructor, we have a state
property where we start the count at zero. Then we increment the count using setState()
.
Okay, let`s do the same Counter
as a functional component, but use Hooks instead.
No more class syntax or constructor, just a plain function.
We import the useState
Hook from React so we can handle our state. useState
returns an array with two members; the first one is the state variable, and the second a function that updates the state. By making use of array destructuring, we can easily get access to the members. Pass a zero as an argument to the useState
hook, and we have our initial state.
const [count, setCount] = useState(0);
Cool, now we can reference our count
state variable directly in our render function and call setCount
when we want to update it.
Effects
When updating the state we can have side effects like data fetching, updating a database or tinkering directly with the DOM.
Side effects is the stuff that needs to happen in your component but can’t be done during rendering.
Take another look at this class-based component where we want to update the document title each time the count change. We will update the title after React has updated the DOM in componentDidMount
and componentDidUpdate
.
This kind of sucks as we have to duplicate the code on the two lifecycle methods for when the component just mounted or if it has updated.
Okay, let`s do the same using Hooks instead.
Nice, now we have a single useEffect
method that takes care of updating the document title. By using this hook, we instructed React to do the work after render when the DOM has been updated. Checkout the console.log
to see when this effect is executed.
useEffect
accepts two arguments; the first one is a callback function containing the side effect logic, and the second an optional array of dependencies. useEffect
will only run the callback if the dependencies has changed between renders and only run once if you pass an empty array.
useEffect(() => {
// this side effect will run only when
// value1 changes
}, [value1]);
useEffect(() => {
// this side effect will run just once,
// after the first render
}, []);
When you need to clean up after an effect has run, for example, to unsubscribe from a subscription to a data source. Return a function in your effect and React will run it before the execution of the next scheduled effect.
useEffect(() => {
service.subscribe(id);
return () => {
service.unsubscribe(id);
};
});
This was a part of the React Hooks series. Checkout the other parts:
What is this React Hooks thing?
State & Effects Hooks
Context Hooks
Reducer Hooks
Custom Hooks
Best Practices