Quick reference for Preact basics — components, hooks, and differences from React.
| 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 |
// 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);
// 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
// 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>;
}
// Rendering lists
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
// Conditional rendering
{isLoggedIn ? <Dashboard /> : <Login />}
{error && <ErrorMessage>{error}</ErrorMessage>}
// 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 };
}