Lesson 16-Preact Hooks

Preact Hooks are Preact’s compatible implementation of React Hooks, enabling you to use state and other Preact features without writing class components. Hooks allow function components to have the same capabilities as class components while keeping code concise and readable.

useState

The useState Hook is the most commonly used Hook for adding state to function components.

Initializing State

import { useState } from 'preact/hooks';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      Count: {count}
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

useEffect

The useEffect Hook allows you to perform side effects, such as data fetching, subscriptions, or manual DOM manipulation.

Running Side Effects After Rendering

import { useEffect } from 'preact/hooks';

function Example() {
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );
}

useContext

The useContext Hook enables function components to consume Context.

Creating Context

import { createContext } from 'preact';

const ThemeContext = createContext('light');

Using Context

import { useContext } from 'preact/hooks';

function Example() {
  const theme = useContext(ThemeContext);

  return (
    <div>
      Current theme is {theme}
    </div>
  );
}

useReducer

The useReducer Hook is an alternative to useState, ideal for managing complex state logic.

Defining a Reducer

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

Using a Reducer

import { useReducer } from 'preact/hooks';

function Example() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>
        Increment
      </button>
      <button onClick={() => dispatch({ type: 'decrement' })}>
        Decrement
      </button>
    </div>
  );
}

useMemo and useCallback

The useMemo and useCallback Hooks optimize performance by preventing unnecessary computations and function recreations.

Using useMemo

import { useMemo } from 'preact/hooks';

function Example() {
  const expensiveComputation = useMemo(() => computeExpensiveValue(a, b), [a, b]);

  return (
    <div>
      Result: {expensiveComputation}
    </div>
  );
}

Using useCallback

import { useCallback } from 'preact/hooks';

function Example() {
  const memoizedCallback = useCallback(
    () => {
      doSomething(a, b);
    },
    [a, b],
  );

  return (
    <div>
      <button onClick={memoizedCallback}>Click me</button>
    </div>
  );
}

useRef

The useRef Hook returns a mutable reference object whose .current property is initialized with the provided argument (initialValue).

Using useRef

import { useRef } from 'preact/hooks';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

Custom Hooks

You can create custom Hooks to encapsulate reusable logic, making it shareable across multiple components.

Creating a Custom Hook

import { useState, useEffect } from 'preact/hooks';

function useDocumentTitle(title) {
  useEffect(() => {
    document.title = title;
  }, [title]);
}

Using a Custom Hook

import { useDocumentTitle } from './customHooks';

function Example() {
  const [count, setCount] = useState(0);
  useDocumentTitle(`You clicked ${count} times`);

  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );
}

Share your love