Preact — Memoization, Callbacks, and Context Hooks
Tags: javascript, webdev, programming, beginners
Published: 2021-01-22 21:38:52

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


Preact is a front end web framework that’s similar to React.

It’s smaller and less complex than React.

In this article, we’ll look at how to get started with front end development with Preact.

### Memoization

We can use the `useMemo` hook to store results of expensive computations.

For example, we can write:

```
import { render } from "preact";
import { useMemo, useState } from "preact/hooks";

const expensive = (a, b) => {
  //...
};

function App() {
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  const memoized = useMemo(() => expensive(a, b), [a, b]);
  //...
  return (
    <div>
      <p>{memoized}</p>
    </div>
  );
}

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}
```

We have the `expensive` function that does some expensive operation.

We call it in the `useMemo` callback to cache its result.

`memoized` is only computed again when `a` or `b` is changed.

We shouldn’t commit any side effects in `useMemo` .

If we need to commit side effects, we should use `useEffect` .

### useCallback

The `useCallback` hook lets us ensure that the returned function is referentially equal until the dependencies change.

For example, we can write:

```
import { render } from "preact";
import { useCallback, useState } from "preact/hooks";
function App() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  const decrement = () => setCount((currentCount) => currentCount - 1);

  const log = useCallback(() => console.log(count), [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={log}>log</button>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}
if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}
```

We pass in a callback into the `useCallback` hook to cache the callback until the `count` state changes.

This lets us prevent the callback from recreated every time the component renders.

### useRef

The `useRef` hook lets us get a reference to a DOM node in a function component.

For instance, we can write:

```
import { render, Fragment } from "preact";
import { useRef } from "preact/hooks";

function App() {
  const input = useRef(null);
  const onClick = () => input.current && input.current.focus();

  return (
    <>
      <input ref={input} />
      <button onClick={onClick}>Focus input</button>
    </>
  );
}
if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}
```

We call the `useRef` hook to return a ref.

Then we assign it to the input with the `ref` prop.

We also create the `onClick` function to get the input element with the `input.current` property and call `focus` on it.

So when we click on Focus Input, the input will be focused.

### useContext

The `useContext` hook lets us access a context in a function component.

For example, we can write:

```
import { createContext, render, Fragment } from "preact";
import { useContext } from "preact/hooks";

const Theme = createContext("light");

function DisplayTheme() {
  const theme = useContext(Theme);
  return <p>Active theme: {theme}</p>;
}

function SomeComponent({ children }) {
  return <>{children}</>;
}

export default function App() {
  return (
    <div>
      <Theme.Provider value="dark">
        <SomeComponent>
          <DisplayTheme />
        </SomeComponent>
      </Theme.Provider>
    </div>
  );
}

if (typeof window !== "undefined") {
  render(<App />, document.getElementById("root"));
}
```

We call `createContext` to create the `Theme` context.

Then we render the `Theme.Provider` in app to set the value of the context.

And we can get the `Theme` context value with the `useContext` hook in the `DisplayTheme` component.

We pass in the context that we want to access.

If our component is inside the `Theme.Provider` then we can access its value.

### Conclusion

We can use hooks to memorize data, cache callbacks, and share data between components with Preact.