Basic Hooks
Introduction to React Hooks
React hooks took front end development by storm in 2019, and has rapidly been gaining popularity ever since. Billed as a way of using state and other React features inside of functional components, hooks offer several other advantages over their class-based predecessors, including:
- Significantly less boilerplate
- Better code reusability and composition
- Better separation of logic
- Increased code readability
- The ability to create custom hooks
- No “this” or bindings
So without further ado, let’s take a look at the 3 most basic (and by far the most commonly used) React hooks!
useState()
As the most basic hook in React, useState()
gives us the ability to add state to functional components. (Prior to hooks, state could only be used inside of class based components with this.setState()
).
useState()
returns both a state value and a function to set (update) the state, using array destructuring. Naming convention best-practices dictate the format [state, setState]
.
For example:
const [darkMode, setDarkMode] = useState(false)
Notice in this example that the state value darkMode
as well as a function for updating the state setDarkMode
are returned from useState()
via array destructuring. You may also notice that an argument has been passed to useState()
(in this case, the boolean false
, but it can be almost anything) - this argument represents the initial state value.
useState()
is best for storing simple, component-specific data such as user inputs, and can be called multiple times inside of each component. In fact, it is best practice to keep useState()
calls as simple as possible; representing only one ‘slice’ of state. This is because unlike when using this.setState()
the old state will not be automatically merged into the new state - the useState()
hook simply returns the new state. A workaround is using the spread
operator, but it is not advised.
useEffect()
By utilizing the useEffect()
hook, we are able to execute effectual code such as an API call or timer inside of functional components. Similarly to the lifecycle methods of class based components, useEffect()
does not run until the component has mounted. Unlike with classes, multiple useEffect()
calls can be made inside of each functional component, allowing code to be separated more logically and by concern.
useEffect()
will run each time the component is re-rendered, unless values are added to its dependency array. If the array is empty, useEffect()
will run only once on component mount. If values are added to the dependency array, useEffect()
will watch for changes to those values and will run when any changes occur.
useContext()
Context allows for more complex data sharing and management without the need for prop drilling. The useContext()
hook significantly improves the developer experience of using React’s Context API by simplifying the boilerplate - no need to set up a contextType, <Consumer>
, or use the render props method!
The same example with useContext:
The useContext()
hook accepts a context object (the value returned from React.createContext()
) and returns the current context for that object. As you can see, it is a much cleaner syntax than the old method, and requires less code.
That's everything for the 3 most basic React Hooks! There are plenty more to learn, but these three hooks will allow you to build out the majority of the functionality of your app. Stay tuned for more where we will be covering useReducer, useRef, useCallback, useMemo, and custom hooks!