Preact — Hooks

John Au-Yeung - Jan 22 '21 - - Dev Community

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.

Hooks

Preact comes with hooks just like React.

We can use them to set states and commit side effects.

For example, we can use them by writing:

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

function useCounter() {
  const [value, setValue] = useState(0);
  const increment = useCallback(() => {
    setValue(value + 1);
  }, [value]);
  return { value, increment };
}

function App() {
  const { value, increment } = useCounter();
  return (
    <div>
      <p>Counter {value}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

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

We create the useCounter hook with the useState and useCallback hooks.

The useState hook lets us create and set a state.

We have the value state and we can set it with the setValue function.

The increment function is created from the useCallback hook.

It takes a callback that lets us create a function to let us set states and commit side effects.

We used the callback to call setValue to set the value of value .

Then in the App component, we use the useCounter hook, which returns the value state and increment function to let us increase value by 1.

We render a button to call increment when we click it.

And we display the latest value of value .

Each instance of a hook is different from each other.

So using them in different places wouldn’t affect its state.

useState

The useState hook lets us create and set a state.

The state change will cause the component to be re-rendered.

Therefore, we can see the latest value of the state.

For example, we can write:

import { render } from "preact";
import { useState } from "preact/hooks";

function App() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  const decrement = () => setCount((currentCount) => currentCount - 1);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

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

We create the increment function which calls the setCount function to update the state.

Also, we can pass in a callback to return the latest value of the state derived from the previous value of the state.

currentCount has the current value of the count state.

So when we click Increment, we see the count increment by 1.

And when we click Decrement, we see count decrease by 1.

useReducer

The useReducer hook takes a function that looks like a Redux reducer.

We can use it to update more complex states.

For example, we can write:

import { render } from "preact";
import { useReducer } from "preact/hooks";

const initialState = 0;
const reducer = (state, action) => {
  switch (action) {
    case "increment":
      return state + 1;
    case "decrement":
      return state - 1;
    case "reset":
      return 0;
    default:
      throw new Error("Unexpected action");
  }
};

function App() {
  const [count, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => dispatch("increment")}>increment</button>
      <button onClick={() => dispatch("decrement")}>decrement</button>
      <button onClick={() => dispatch("reset")}>reset</button>
    </div>
  );
}

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

We create the reducer function, which takes the state and action parameters.

state has the state.

action has the action name we pass into the dispatch function.

In App , we use the useReducer hook by passing in the reducer function and the initialState , which has the initial value of count .

Then we call the dispatch function to update the count state.

Conclusion

We can use various hooks with the Preact hooks package.

Also, we can compose hooks to create other hooks.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .