Preact Documentation

website·Indexed 40 days ago

https://preactjs.com/

Documentation for Preact v10, a lightweight 3kB alternative to React. Covers getting started with Vite-powered apps, pipeline integration, JSX configurations, tree-shaking with named exports, and using preact/compat for React compatibility.

Tokens
24.1K
Snippets
162
Records
175
Agent score
25%

What's inside Preact

  1. Introduction to Preact Hooks

    Hooks provide an alternative to class components, allowing you to extract stateful logic and side effects into reusable functions. Hooks rely on closures rather than the this keyword, eliminating many stale data problems associated with asynchronous state updates. Hooks can be imported from preact/hooks or preact/compat.
  2. Handle table nesting in Preact

    Preact warns about improper table nesting because browsers automatically correct invalid HTML (e.g., wrapping a <tr> directly inside a <table> with a <tbody>). Since Preact's VDOM expects the structure provided in code, this browser-level correction creates a mismatch between the VDOM and the real DOM, leading to rendering errors.
  3. Label custom hooks in DevTools with useDebugValue

    The useDebugValue hook allows developers to display a custom label for a hook within the Preact DevTools browser extension. This provides better context about the state or value a custom hook represents. It accepts a value as the first argument and an optional formatter function as the second argument.
    import { useDebugValue, useState } from 'preact/hooks';
    
    function useCount() {
    	const [count, setCount] = useState(0);
    	// Simple label
    	useDebugValue(count > 0 ? 'Positive' : 'Negative');
    	// Or use a formatter function
    	useDebugValue(count, c => `Count: ${c}`);
    	return [count, setCount];
    }
  4. Install and use preact-render-to-string for SSR

    Server-Side Rendering (SSR) in Preact is provided by the preact-render-to-string package. It allows rendering a Preact tree into an HTML string for faster initial load times or testing.
    npm install -S preact-render-to-string
  5. Build Preact apps without build tools using Import Maps

    Preact supports no-build workflows by leveraging browser-native Import Maps. This allows you to use bare specifiers (like import { render } from 'preact') which the browser resolves to CDN URLs.

    When using CDNs like esm.sh, use the ?external=preact query parameter for dependencies (like htm/preact or @preact/signals) to ensure only one single instance of Preact is loaded, as Preact must be used as a singleton.

    <!DOCTYPE html>
    <html>
    	<head>
    		<script type="importmap">
    			{
    				"imports": {
    					"preact": "https://esm.sh/preact@10.23.1",
    					"preact/": "https://esm.sh/preact@10.23.1/",
    					"@preact/signals": "https://esm.sh/@preact/signals@1.3.0?external=preact",
    					"htm/preact": "https://esm.sh/htm@3.1.1/preact?external=preact"
    				}
    			}
    		</script>
    	</head>
    	<body>
    		<div id="app"></div>
    		<script type="module">
    			import { render } from 'preact';
    			import { html } from 'htm/preact';
    
    			export function App() {
    				return html`<h1>Hello, World!</h1>`;
    			}
    
    			render(html`<${App} />`, document.getElementById('app'));
    		</script>
    	</body>
    </html>
  6. Handle custom events in Web Components

    While Preact normalizes standard DOM events (e.g., onChange for change), it preserves the exact casing for unrecognized event handler props. This allows support for case-sensitive custom events fired by Web Components.
    // Listens for the case-sensitive "TabChange" event
    <tab-bar onTabChange={() => console.log('tab change')} />
    
    // Listens for the lower-case "tabchange" event
    <tab-bar ontabchange={() => console.log('tab change')} />
  7. Install Enzyme and Preact adapter for unit testing

    If you prefer using Enzyme for unit testing Preact components, you must install Enzyme along with the specific Preact adapter.
    npm install --save-dev enzyme enzyme-adapter-preact-pure
  8. Implement isomorphic routing with preact-iso

    preact-iso provides an async-aware router that works seamlessly across both browser and server environments. It supports synchronous and asynchronous route loading via lazy(). When a route suspends (throws a Promise), the router preserves the current route until the new one is ready, avoiding empty loading states. It also supports progressive hydration, where deferred imports are hydrated only after the route's promise resolves.
    import { 
    	lazy, 
    	LocationProvider, 
    	ErrorBoundary, 
    	Router, 
    	Route 
    } from 'preact-iso';
    
    // Synchronous route
    import Home from './routes/home.js';
    
    // Asynchronous routes (throws a promise)
    const Profiles = lazy(() => import('./routes/profiles.js'));
    const Profile = lazy(() => import('./routes/profile.js'));
    const NotFound = lazy(() => import('./routes/_404.js'));
    
    function App() {
    	return (
    		<LocationProvider>
    			<ErrorBoundary>
    				<Router>
    					<Home path="/" />
    					{/* Use <Route> for better TypeScript support */}
    					<Route path="/profiles" component={Profiles} />
    					<Route path="/profile/:id" component={Profile} />
    					{/* 'default' prop indicates a fallback/404 route */}
    					<NotFound default />
    				</Router>
    			</ErrorBoundary>
    		</LocationProvider>
    	
    	);
    }
  9. Batch multiple signal updates

    Use the batch(fn) function to combine multiple signal updates into a single 'commit'. This prevents intermediate effects from running until the batch callback completes, improving performance.
    import { signal, batch } from '@preact/signals';
    
    const todos = signal([]);
    const text = signal('');
    
    function addTodo() {
    	batch(() => {
    		todos.value = [...todos.value, { text: text.value }];
    		text.value = '';
    	});
    }
  10. Enable Preact debug warnings and developer tools

    To enable helpful warnings, errors, and support for the Preact Developer Tools browser extension, import preact/debug at the top of your main entry file.
    import 'preact/debug'; // Add this line at the top of your main entry file
  11. Use HTML attributes like 'class' in Preact JSX

    Preact detects whether a prop should be set as a property or an HTML attribute. This allows developers to use standard HTML attribute names like class instead of the React-specific className in JSX. Both class and className are supported.
    // Both are equivalent in Preact
    <div class="foo" />
    <div className="foo" />
  12. Update context values dynamically

    To update context values dynamically, pass a state-updating function (like a useState setter) through the context provider's value prop. This allows any consuming component to trigger a state change in the provider.
    import { render, createContext } from 'preact';
    import { useContext, useState } from 'preact/hooks';
    
    const ThemePrimary = createContext(null);
    
    function ThemePicker() {
    	const { theme, setTheme } = useContext(ThemePrimary);
    	return <input type="color" value={theme} onChange={e => setTheme(e.currentTarget.value)} />;
    }
    
    function App() {
    	const [theme, setTheme] = useState('#673ab8');
    	return (
    		<ThemePrimary.Provider value={{ theme, setTheme }}>
    			<ThemePicker />
    		</ThemePrimary.Provider>
    	);
    }