React — Shifting From Classes to Hooks
When coding in React, do you find yourself often wondering “Should I make this component a class component or functional component?” Then, because you’re not sure you need state, you decide with functional components for its efficiency and you don’t want to deal with class lifecycles, yadda yadda. And then much later, this decision comes back to bite you because you suddenly need state in the component. At last, you start questioning your life choices as you begin switching your code to class syntax — extend Component
, this.props
, render()
, etc.
Well, you’re in luck! Hooks are your answer.
React 16.8.0 (released February 2019) introduced Hooks — a way to use state and other React features without writing a class¹. This doesn’t mean you have to go back and switch all of your class components to functional components and add Hooks. However, you can gradually start implementing Hooks as you build onto your existing code.
Quick notes —
- Hooks do not work in class components
- Only call Hooks from React function components, not regular JavaScript functions
- Hooks can be called from custom Hooks
- Only call Hooks at the top level. Don't call Hooks inside loops, conditions, or nested functions.
Classes vs Hooks — State
useState
is a Hook that allows you to add state to function components. And you don’t have to worry about binding this
!
useState
accepts the initial state as an argument and it returns the current state value and a function that lets you update it¹. In a class, this looks like state = {}
, this.state
, and this.setState()
².
In this example, clicking the button will add a plate to your stack of plates at this Sushi Bar. Comparing the two code, essentially this.state.plate
=plate
, this.setState
= setPlate
. Note — setPlate
does not merge changes with the initial state, but instead it replaces it.
In line 20, this syntax allows the return values of useState
to be assigned to a variable via destructuring.
Classes vs Hooks — Lifecycle Methods
If you’re familiar with React class lifecycle methods, you can think of useEffect
Hook as componentDidMount
, componentDidUpdate
, and componentWillUnmount
combined³.
Currently, there are no equivalents for getSnapshotBeforeUpdate
, componentDidCatch
and getDerivedStateFromError
, but they will be added soon.
In this example, the Sushi Bar has become an all-you-can-eat-sushi, but with a 10 minute timer.
In classes, componentDidMount
and componentWillUnmount
generally mirror each other if you want to avoid bugs especially if you have side effects that require clean-up. With useEffect
, if your effect returns a function (which is optional), React will run it when it is time to clean up³. Instead of separating out the logic into different functions, this keeps them close together and easier to keep track of.
Note — useEffect
runs on every re-render.
Callbacks and Props
Hooks are also customizable and useful for passing information between Hooks. Passing information from parent to child components, utilizing props is the same. For passing information from child to parent, see more on custom hooks.
Resources
References
¹ Hooks at a Glance. (n.d.). Retrieved August 13, 2020, from https://reactjs.org/docs/hooks-overview.html
² Using the State Hook. (n.d.). Retrieved August 13, 2020, from https://reactjs.org/docs/hooks-state.html
³ Using the Effect Hook. (n.d.). Retrieved August 13, 2020, from https://reactjs.org/docs/hooks-effect.html