Evan Cordulack

React Hooks Notes

January 02, 2020

From: "Sophie Alpert and Dan Abramov's sections of the React Today and Tomorrow and 90% Cleaner React With Hooks talk" https://youtu.be/dpw9EHDh2bM (this is about the first hour of the video)

Hooks Overview

React Hooks are a set of functions defined by React that you can call inside of a function component. They give you access to features (like state) previously only available to components defined using the JS class syntax.

While defining a component with a class works just fine, it often leads to several problems in our React code:

  • It is hard to share logic between components (which can lead to "wrapper hell" where you have a component nested inside many other components)
  • Components can get large because tasks have to be split across different lifecycle methods
  • Classes can be difficult to understand.

Hooks address each of these problems. We can use hooks to share code between components while accessing a component's state. They also simplify how we use React's lifecycle methods which allows us to better organize our code. Finally, they can help us get rid of some of the boilerplate code associated with component-related classes.

Backwards Compatible: "Classes can work side-by-side with hooks and while hooks represent [the React team's] vision for the future of React, [they] don't want to make breaking changes...[and] keep classes working"

Adding State to Function Components

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me

from https://reactjs.org/docs/hooks-intro.html

Instead of using this.state, you can call useState() with the default value of your variable. Using array destructuring, we use the return value from useState to set the name of your variable and the function name we will call to set that variable.

"How does React know which useState variable corresponds to which useState call?"

  • React relies on the order of the useState() calls. In order for this to work, you can't call a hook inside of a conditional

Hooks & Lifecycle Methods with useEffect()

"The ability to perform side-effects is another core feature of React components"

You can now perform side-effects using a React hook instead of lifecycle methods like componentDidMount() by calling the useEffect() hook

  • "By default, useEffect runs both after the initial render and after every update"
    • There is a way to opt out of this. That would be helpful, for example, if you are subscribing to something like the browser api to tell you the width of the window. You don't want to unsubscribe and resubscribe to this every time the component updates.
  • Because you define useEffect in your function (and use an arrow function with it), you can get access to any state, context, effect, etc. variables that you have already defined (so you don't need to mess with this.state.yourVar and instead can just use yourVar)

Cleaning up after calling useEffect

  • Any effect can return a function. If you return a function, React will call that function after the effect is called. You can use this to clean up your function (for example, you can set an event listener in useEffect and then remove the listener in the function useEffect returns

  • You can call useEffect multiple times. This means that you can you organize your code based on what it is doing instead of when it gets called.

Sharing Code Between Components Using Hooks

With the addition of hooks, your function components are going to get larger, and that's cool with the React team. However, you might want to reuse some of the code in other components or test it separately.

  • Because components and hooks are both functions, we can share logic between functions by extracting the code to a different function.
  • The functions you create are called "custom hooks"
    • Always start your custom hook name with "use". This allows you to look at a function and know if it can have its own state. It also allows React's linting tool to check to make sure you aren't calling a hook inside of a conditional