Things I've Learned About React & Hooks
1 min read

Things I've Learned About React & Hooks

  • When I first started using React, it was unclear what role useRef played, outside of providing access to a DOM node when used with the ref attribute. The important distinction is that useState triggers a re-render, while useRef doesn't, so they can really be thought of as two ways of maintaining local state.
  • Inside useEffect, you can return a function which runs whenever the component unmounts. This is super helpful for canceling pending async requests, or cleaning up any state which might be effected by an unmount.
  • Use custom hooks liberally. There's really very little downside if they contain some stateful logic that's used in multiple places.
  • Sometimes, you need to trigger a re-render when an external event happens, like a window resize. The right way to do this is to create a hook with an event listener, and have the listener update some internal state, so even if you don't care about the size of the window, just having useViewportSize() in your component will make sure it always re-renders as needed.
  • Sometimes, you want to call setState without having access to the current state, either because it's not in scope, or because you're in a stale closure. setState allows you to pass in a function which receives the previous state as an argument. For instance, if you have [showLabel, setShowLabel] and you want to toggle the value, you can call setShowLabel(prev => !prev) to flip it.
  • You should use Contexts sparingly. They add cognitive overhead and tightly couple your components. However, they're invaluable when several components need to share state. My rule of thumb is that I'll consider a context if I'm passing a prop down more than one level (prop drilling), but I'll almost always use one if I'm passing a prop down more than two levels.
  • Let's say you have a UserContext, it can be helpful to export a useUserProvider hook from the same file. That way, instead of having to import { useContext } and import { UserContext }, you can just do import { useUserProvider } and save some typing.