The slightly misleading terminology of react hooks
Tags: javascript, react, functional
Published: 2021-02-05 23:08:32

So react hooks are awesome, they make components much simpler, they let you abstract your component logic and completely do away with class components.

However; the names of these hooks are somewhat misleading. Especially after react went all functional on us with function components.

Allow me to elaborate:

## Side Effects
What is a side effect? A side effect is when a function changes another part of an application outside of its own scope:

```ts
function goHome() {
  window.location.href = '/home';
}
```
Calling this function is updating the window location, which is a global variable and isn't part of its own scope, so it's a side effect.

It's also worth quickly also covering side effect's partner-in-crime:

## Idempotent
An idempotent function will return the same value for the same set of inputs every time.

```ts
function getPath() {
  return window.location.pathname;
}
```
This function is _not_ idempotent. If the location were to change, you would get a different result.

With that out of the way, let's talk about `useEffect`:

## useEffect
> Accepts a function that contains imperative, possibly effectful code.

```ts
useEffect(() => {
  window.location.href = '/home';
}, []);
```

The useEffect hook _allows_ you to do effectful behaviour inside a functional component.

If you do a side effect inside useEffect, react pushes that side effect to the end of the render cycle. In react terms, useEffect is about protecting the render cycle, not about removing side effects.

Why is this distinction important? We often talk about react components as being "pure". A pure component should be side-effect-free and idempotent. Wrapping your side effects in useEffect does not mean your component is still pure.

## useState
I've seen many people say things like "we don't need smart/dumb components now we have hooks"  
I don't want to go in-depth into patterns and architecture, but just because you're using useState instead of redux, etc, you're still introducing state into a component. This breaks a component's idempotency.

For every piece of state a component manages, the harder it is to reason about, test, and control that component.  
Tl;dr useState is no different to any other component state - it is _not_ functional.

## Function vs Functional component
Okay something that I only really noticed recently: we always talk about `functional` components but actually, the docs refer to these as `function` components. What's the difference?

I believe the difference is this:

A `functional` component adheres to the rules of Functional Programming. It is idempotent, pure, and stateless.

A `function` component is just any old component that just happens to be a function.

That's a pretty big discrepancy. When we're talking about function components, do we care about whether it's a functional component?

I used to believe that yes; any function component should be side-effect and state free. Now I'm not so sure.

## Conclusion
We've definitely got some confusing terminology here. `useEffect` is not offering some way of keeping effects "out" of your component. And a `function` component is not the same as a `functional` component.

## Should I stop using hooks?
Absolutely not. Hooks are awesome. I just want us to be mindful that hooks are not some magical construct that preserves function purity. If your component has state or causes side effects, `useState` and `useEffect` do not change this fact.