Preact Cheatsheet

Quick reference for Preact basics — components, hooks, and differences from React.

Components

Concept Description
Function component function App() {} — same as React
Arrow component const App = () => {} — concise alternative
Class component class App extends Component {} — supported but not preferred
JSX <div>{expr}</div> — same syntax as React
Fragment <>...</> — grouping without extra DOM node

Hooks

// Preact exports hooks from 'preact/hooks'
import { useState, useEffect, useRef, useMemo, useCallback } from 'preact/hooks';

// useState
const [count, setCount] = useState(0);

// useEffect
useEffect(() => {
  const id = setInterval(() => setCount(c => c + 1), 1000);
  return () => clearInterval(id);
}, []);

// useRef
const inputRef = useRef<HTMLInputElement>(null);

// useMemo / useCallback
const sorted = useMemo(() => items.sort(), [items]);
const handler = useCallback((id: string) => select(id), [select]);

// useReducer
const [state, dispatch] = useReducer(reducer, initialState);

Key Differences from React

// Preact uses native browser events (not SyntheticEvent)
function handleClick(e: MouseEvent) {
  // e is a real DOM MouseEvent
  console.log(e.target);
}

// No automatic batching in Preact 10
// State updates in event handlers batch naturally

// Smaller bundle size (~4KB vs ~40KB for React)
// install: npm install preact

// Compatibility layer for React libraries
// npm install preact/compat
// In your bundler alias: react -> preact/compat

State & Props

// Props with TypeScript
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary";
}

function Button({ label, onClick, variant = "primary" }: ButtonProps) {
  return <button onClick={onClick}>{label}</button>;
}

// Merging props
function Badge({ children, ...rest }: JSX.HTMLAttributes<HTMLSpanElement>) {
  return <span {...rest}>{children}</span>;
}

Lists & Conditional Rendering

// Rendering lists
<ul>
  {items.map((item) => (
    <li key={item.id}>{item.name}</li>
  ))}
</ul>

// Conditional rendering
{isLoggedIn ? <Dashboard /> : <Login />}
{error && <ErrorMessage>{error}</ErrorMessage>}

Context & Custom Hooks

// Creating context
import { createContext } from 'preact';
import { useContext } from 'preact/hooks';

const ThemeContext = createContext<"light" | "dark">("light");

// Provider
<ThemeContext.Provider value="dark">
  <App />
</ThemeContext.Provider>

// Consuming context
const theme = useContext(ThemeContext);

// Custom hook — same pattern as React
function useToggle(initial = false) {
  const [on, setOn] = useState(initial);
  const toggle = () => setOn(prev => !prev);
  return { on, toggle, setOn };
}