The Startup
Published in

The Startup

Learning About React Hooks — A Coffee Lover’s Perspective

I became interested in hooks after I read Smart and Dumb Components (I actually mostly focused on the disclaimer at the end) while learning about React and building Catoro, a coffee tasting app.

Right after I began planning Catoro, the importance of Hooks became relevant when I laid out my app flow. This is how my first draft looked:

Catoro App Flow (beginning Draft)

As you can see as I was building my app. I was starting to develop a flow of having two ‘smart’ containers one for TableCuppings (TablesContainer) and another for Home related stuff (HomeContainer).

However, as I was building the different parts of the app, the logic and passing in-out props was becoming out of hand and I was starting to lose the sense of app flow (as well of myself). So back to get some more coffee and to the drawing board.

Long story short. Bring on hooks to the rescue!

What are hooks?

As you might know, React’s foundation are components, which are basically Javascript functions (written as JSX) that then render HTML elements on the screen. In the most basic sense components are thought to be either class or functional. The traditional way of distinguishing class vs functional goes as follows:

  1. Syntax: Functional components are basic JS functions, accepting arguments as props and returning JSX elements. Class components use ES6 class syntax, also require to extend from React.Component. Class components are more bulky and functional tend to be leaner in code length.
  2. State: Class components by extending from React.Component have access to state and local state management. This state is usually passed down as props to functional components, which its sole ‘function’ is to render JSX on this line of thought.
  3. Lifecycle Methods: Class component have access to lifecycle methods such as componentDidMount() and componentDidUpdate(). The benefits of this means to initiate a fetch request, or to check on previous props change to initiate other requests or do state management.

This distinction has changed. With hooks, points #2 and #3 are no longer entirely applicable. So with the introduction of ‘hooks’ like useState and useEffect it makes this distinction less rigid and now more a matter of choice and style.

How hooks caffeinated Catoro

While I didn’t end up getting rid of my class containers entirely, I ended up using a mixture of both approaches. However, hooks such asuseState really helped my functional components be more efficient. This was the case withEditTable.

Here’s an example of how EditProfile ‘used’ state:

export default function EditTable({table}) {
..
const [name, setName] = useState( table.name || "");(...)
//form Name input
<Form.Group controlId="formBasicTextF2" >
<Form.Label>Cupping Table Name</Form.Label> <Form.Control type="text" value={name} onChange={e => setName(e.target.value)}
...etc

You might see from this focused example from Catoro source code, how useState was used in const [name, setName] = useState( table.name || “”) and onChange={e => setName(e.target.value)}.

useState requires us to define both a variable and a setter when we ‘useState’. In this case, name was added to state as either name being passed from table or an empty string. Then on our onChange, we passed it directly to the setName setter and boom. Our state is easily updated.

Catoro used React Form Hook, a form helper which uses extensively (as its name implies) hooks.

My CuppingScoreForm functional component took this to the next level and usedState on steroids. By the use of Form Hook helper, it was able to achieve user validation, errorHandling and getting data sanitized for submission all by usingState.

More hooks to the rescue

There are other very useful implementations of hooks such as useEffect, useReducer, and useContext. I will briefly explain them here for informational purposes.

useEffect kind of implements lifecycle methods componentDidMount() and componentDidUpdate() within the same function. useEffect also uses two arguments, the first one is invoked after the render, and the second, an optional array, when the effect should be called.

There’s a neat article that you can read to see useEffect in action. In Catoro, for a brief time, I implemented the article’s example to detect a click outside of ExportPreview. However, in the end, this functional model ended up being rendered in a separate window.

Nonetheless, to get a sense of how useState works, this is how my code looked when I implemented useEffect to handle a click outside (bonus point it uses useRef):

import {useRef, useEffect} from "react";const ExportPreview = () => {  const node = useRef();  const handleClick = e => {  if (node.current.contains(e.target)) {  // inside click, you can have a function but I returned  return;  }  // outside click  toggleExportPreview() };useEffect(() => { // add when mounted   document.addEventListener("mousedown", handleClick);  // return function to be called when unmounted return () => {   document.removeEventListener("mousedown", handleClick);  };});return (<Container className="exportPreview"
//this is how you'll ref the node.
ref={node}>...etc

I think with these two examples, you’re now getting the hang of React hooks! So you might get a sense of whatuseReducer, and useContext could be used for.

useReducer also takes two arguments, and in this case, the second argument is a dispatch function. With that in mind, you could do something along these lines:

const likesHandler = (props) => {
const [likesState, dispatchLikes] = useReducer(reducer, { likes: 0 })

return (
<>
<h1>Liker</h2>
<Button
onClick={() => dispatchLikes({type: 'INCREASE_LIKES', payload: 1}) }
...etc

useContext is another basic hook. It basically lets you avoid to have to send down state by now accepting a context object.

I will let you read this one for yourself! You can check the React Hooks API Documentation. It will also give you a good extended overview of all the hooks explained so far.

Hope this made your understanding of React Hooks a bit better. Now get back to coding! I’d love to see what you guys are doing with hooks.

For me back to another cup of coffee.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store