# Preact > Components represent the basic building block in Preact. They are fundamental in making it easy to build complex UIs from little building blocks. They're also responsible for attaching state to our re --- # Source: https://preactjs.com/guide/v10/components#error-boundaries # Source: https://preactjs.com/guide/v10/components#fragments # Components Components represent the basic building block in Preact. They are fundamental in making it easy to build complex UIs from little building blocks. They're also responsible for attaching state to our rendered output. There are two kinds of components in Preact, which we'll talk about in this guide. --- * [Functional Components](#functional-components) * [Class Components](#class-components) * [Lifecycle Methods](#lifecycle-methods) * [Error Boundaries](#error-boundaries) * [Fragments](#fragments) --- ## Functional Components Functional components are plain functions that receive `props` as the first argument. The function name **must** start with an uppercase letter in order for them to work in JSX. ```jsx function MyComponent(props) { return
My name is {props.name}.
; } // Usage const App = ; // Renders:
My name is John Doe.
render(App, document.body); ``` > Note in earlier versions they were known as `"Stateless Components"`. This doesn't hold true anymore with the [hooks-addon](/guide/v10/hooks). ## Class Components Class components can have state and lifecycle methods. The latter are special methods, that will be called when a component is attached to the DOM or destroyed for example. Here we have a simple class component called `` that displays the current time: ```jsx class Clock extends Component { state = { time: Date.now() }; // Lifecycle: Called whenever our component is created componentDidMount() { // update time every second this.timer = setInterval(() => { this.setState({ time: Date.now() }); }, 1000); }; // Lifecycle: Called just before our component will be destroyed componentWillUnmount() { // stop when not renderable clearInterval(this.timer); }; render() { let time = new Date(this.state.time).toLocaleTimeString(); return {time}; } } ``` ### Lifecycle Methods In order to have the clock's time update every second, we need to know when `` gets mounted to the DOM. _If you've used HTML5 Custom Elements, this is similar to the `attachedCallback` and `detachedCallback` lifecycle methods._ Preact invokes the following lifecycle methods if they are defined for a Component: | Lifecycle method | When it gets called | | --- | --- | | `componentWillMount()` | (deprecated) before the component gets mounted to the DOM | | `componentDidMount()` | after the component gets mounted to the DOM | | `componentWillUnmount()` | prior to removal from the DOM | | `componentWillReceiveProps(nextProps, nextContext)` | before new props get accepted _(deprecated)_ | | `getDerivedStateFromProps(nextProps, prevState)` | just before `shouldComponentUpdate`. Return object to update state or `null` to skip update. Use with care. | | `shouldComponentUpdate(nextProps, nextState, nextContext)` | before `render()`. Return `false` to skip render | | `componentWillUpdate nextProps, nextState, nextContext)` | before `render()` _(deprecated)_ | | `getSnapshotBeforeUpdate(prevProps, prevState)` | called just after `render()`, but before changes are flushed to the DOM. Return value is passed to `componentDidUpdate`. | | `componentDidUpdate(prevProps,prevState, snapshot)` | after `render()` | Here's a visual overview of how they relate to each other (originally posted in [a tweet](https://web.archive.org/web/20191118010106/https://twitter.com/dan_abramov/status/981712092611989509) by Dan Abramov): ![Diagram of component lifecycle methods](/guide/components-lifecycle-diagram.png) ### Error Boundaries An error boundary is a component that implements either `componentDidCatch()` or the static method `getDerivedStateFromError()` (or both). These are special methods that allow you to catch any errors that happen during rendering and are typically used to provide nicer error messages or other fallback content and save information for logging purposes. It's important to note that error boundaries cannot catch all errors and those thrown in event handlers or asynchronous code (like a `fetch()` call) need to be handled separately. When an error is caught, we can use these methods to react to any errors and display a nice error message or any other fallback content. ```jsx class ErrorBoundary extends Component { state = { errored: false }; static getDerivedStateFromError(error) { return { errored: true }; } componentDidCatch(error, errorInfo) { errorReportingService(error, errorInfo); } render(props, state) { if (state.errored) { return

Something went badly wrong

; } return props.children; } } ``` ### Fragments A `Fragment` allows you to return multiple elements at once. They solve the limitation of JSX where every "block" must have a single root element. You'll often encounter them in combination with lists, tables or with CSS flexbox where any intermediate element would otherwise affect styling. ```jsx import { Fragment, render } from 'preact'; function TodoItems() { return (
  • A
  • B
  • C
  • ); const App = (
    • D
    ); render(App, container); // Renders: //
      //
    • A
    • //
    • B
    • //
    • C
    • //
    • D
    • //
    ``` Note that most modern transpilers allow you to use a shorter syntax for `Fragments`. The shorter one is a lot more common and is the one you'll typically encounter. ```jsx // This: const Foo = foo; // ...is the same as this: const Bar = <> /foo ; ``` You can also return arrays from your components: ```jsx function Columns() { return [Hello, World]; } ``` Don't forget to add keys to `Fragments` if you create them in a loop: ```jsx function Glossary(props) { return (
    {props.items.map(item => ({ // Without a key, Preact has to guess which elements have // changed when re-rendering. key: item.id,
    {item.term}
    {item.description}
    }))
    ); } ``` --- # Source: https://preactjs.com/guide/v10/context#createcontext # Context Context is a way to pass data through the component tree without having to pass it through every component in-between via props. In a nutshell, it allows components anywhere in the hierarchy to subscribe to a value and get notified when it changes, bringing pub-sub-style updates to Preact. It's not uncommon to run into situations in which a value from a grandparent component (or higher) needs to be passed down to a child, often without the intermediate component needing it. This process of passing down props is often referred to as "prop drilling" and can be cumbersome, error-prone, and just plain repetitive, especially as the application grows and more values have to be passed through more layers. This is one of the key issues Context aims to address by providing a way for a child to subscribe to a value higher up in the component tree, accessing the value without it being passed down as a prop. There are two ways to use context in Preact: via the newer `createContext` API and the legacy context API. These days there's very few reasons to ever reach for the legacy API but it's documented here for completeness. --- ### Modern Context API #### Creating a Context To create a new context, we use the `createContext` function. This function takes an initial state as an argument and returns an object with two component properties: `Provider`, to make the context available to descendants, and `Consumer`, to access the context value (primarily in class components). ```jsx import { createContext } from 'preact'; export const Theme = createContext('light'); export const User = createContext({ name: 'Guest' }); export const Locale = createContext(null); ``` #### Setting up a Provider Once we've created a context, we must make it available to descendants using the `Provider` component. The `Provider` must be given a `value` prop, representing the initial value of the context. > The initial value set from `createContext` is only used in the absence of a `Provider` above the consumer in the tree. This may be helpful for testing components in isolation, as it avoids the need for creating a wrapping `Provider` around your component. ```jsx import { createContext } from 'preact'; export const Theme = createContext('light'); function App() { return ( ); } ``` > **Tip:** You can have multiple providers of the same context throughout your app but only the closest one to the consumer will be used. #### Using the Context There are three ways to consume a context, largely dependent on your preferred component style: `static contextType` (class components), the `useContext` hook (function components/hooks), and `Context.Consumer` (all components). ```jsx const ThemePrimary = createContext('#673ab8'); class ThemedButton extends Component { static contextType = ThemePrimary; render() { const theme = this.context; return ( ); } } function App() { return ( ); } ``` ```jsx const ThemePrimary = createContext('#673ab8'); function ThemedButton() { const theme = useContext(ThemePrimary); return ( ); } function App() { return ( ); } ``` ```jsx const ThemePrimary = createContext('#673ab8'); function ThemedButton() { return ( {theme => ( )} ); } function App() { return ( ); } ``` #### Updating the Context Static values can be useful, but more often than not, we want to be able to update the context value dynamically. To do so, we leverage standard component state mechanisms: ```jsx const ThemePrimary = createContext(null); function ThemedButton() { const { theme } = useContext(ThemePrimary); return ( ); } function ThemePicker() { const { theme, setTheme } = useContext(ThemePrimary); return ( setTheme(e.currentTarget.value)} /> ); } function App() { const [theme, setTheme] = useState('#673ab8'); return ( {' - '} ); } ``` --- ### Legacy Context API This API is considered legacy and should be avoided in new code, it has known issues and only exists for backwards-compatibility reasons. One of the key differences between this API and the new one is that this API cannot update a child when a component in-between the child and the provider aborts rendering via `shouldComponentUpdate`. When this happens, the child **will not** receive the updated context value, often resulting in tearing (part of the UI using the new value, part using the old). To pass down a value through the context, a component needs to have the `getChildContext` method, returning the intended context value. Descendants can then access the context via the second argument in function components or `this.context` in class-based components. ```jsx function ThemedButton(_props, context) { return ( ); } class App extends Component { getChildContext() { return { (theme: '#673ab8') }; } render() { return (
    ); } } ``` ```bash Run in REPL --- # Source: https://preactjs.com/guide/v10/debugging # Debugging Preact Apps Preact ships with a lot of tools to make debugging easier. They're packaged in a single import and can be included by importing `preact/debug`. These include integration with our own [Preact Devtools](https://preactjs.github.io/preact-devtools/) Extension for Chrome and Firefox. We'll print a warning or an error whenever we detect something wrong like incorrect nesting in `` elements. --- ## Installation The [Preact Devtools](https://preactjs.github.io/preact-devtools/) can be installed in the extension store of your browser. - [For Chrome](https://chrome.google.com/webstore/detail/preact-developer-tools/ilcajpmogmhpliinlbcdebhbcanbghmd) - [For Firefox](https://addons.mozilla.org/en-US/firefox/addon/preact-devtools/) - [For Edge](https://microsoftedge.microsoft.com/addons/detail/hdkhobcafnfejjieimdkmjaiihkjpmhk) Once installed, we need to import `preact/debug` somewhere to initialize the connection to the extension. Make sure that this import is **the first** import in your whole app. > `@preact/preset-vite` includes the `preact/debug` package automatically. You can safely skip the setup & strip steps if you're using it! Here is an example of how your main entry file to your application may look like. ```jsx // Must be the first import import 'preact/debug'; import { render } from 'preact'; import App from './components/App'; render(, document.getElementById('root')); ``` ### Strip devtools from production Most bundlers allow you to strip out code when they detect that a branch inside an `if` statement will never be hit. We can use this to only include `preact/debug` during development and save those precious bytes in a production build. ```jsx // Must be the first import if (process.env.NODE_ENV === 'development') { // Must use require here as import statements are only allowed // to exist at top-level. require('preact/debug'); } import { render } from 'preact'; import App from './components/App'; render(, document.getElementById('root')); ``` Make sure to set the `NODE_ENV` variable to the correct value in your build tool. ## Debug Warnings and Errors Sometimes you may get warnings or errors when Preact detects invalid code. These should be fixed to ensure that your app works flawlessly. ### `undefined` parent passed to `render()` This means that the code is trying to render your app into nothing instead of a DOM node. It's the difference between: ```jsx // What Preact received render(, undefined); // vs what it expected render(, actualDomNode); ``` The main reason this error occurs is that the DOM node isn't present when the `render()` function is called. Make sure it exists. ### `undefined` component passed to `createElement()` Preact will throw this error whenever you pass `undefined` instead of a component. The common cause for this one is mixing up `default` and `named` exports. ```jsx // app.js export default function App() { return
    Hello World
    ; } // index.js: Wrong, because `app.js` doesn't have a named export import { App } from './app'; render(, dom); ``` The same error will be thrown when it's the other way around. When you declare a `named` export and are trying to use it as a `default` export. One quick way to check this (in case your editor won't do it already), is to just log out the import: ```jsx // app.js export function App() { return
    Hello World
    ; } // index.js import App from './app'; console.log(App); // Logs: { default: [Function] } instead of the component ``` ### Passed a JSX literal as JSX twice Passing a JSX Literal or Component into JSX again is invalid and will trigger this error. ```jsx const Foo =
    foo
    ; // Invalid: Foo already contains a JSX-Element render(Foo, dom); ``` To fix this, we can just pass the variable directly: ```jsx const Foo =
    foo
    ; render(Foo, dom); ``` ### Improper nesting of table detected HTML parsers have very strict rules on how tables should be structured, deviating from which will lead to rendering errors that can be hard to debug. To help with this, Preact can detect improper nesting in a number of situations and will print warnings to catch this early. To learn more about how tables should be structured, we can highly recommend [the MDN documentation](https://developer.mozilla.org/en-US/docs/Learn/HTML/Tables/Basics). > **Note:** In this context, "strict" is referring to the _output_ of the HTML parser, not the _input_. Browsers are quite forgiving and try to correct invalid HTML where they can to ensure that pages can still be displayed. However, for VDOM libraries like Preact, this can lead to issues as the input content might not match the output once the browser has corrected it, which Preact will not be made aware of. > > For example, `
    ` elements must always be a child of ``, ``, or `` elements per the spec, but if you were to write a `` directly inside of a `
    `, the browser will attempt to correct this by wrapping it in a `` element for you. Preact will therefore expect the DOM structure to be `
    ` but the real DOM constructed by the browser would be `
    `. ### Invalid `ref`-property When the `ref` property contains something unexpected, we'll throw this error. This includes string-based `refs` that have been deprecated a while ago. ```jsx // valid
    {/* ... */}} /> // valid const ref = createRef();
    // Invalid
    ``` ### Invalid event handler Sometimes you'll may accidentally pass a wrong value to an event handler. They must always be a `function` or `null` if you want to remove it. All other types are invalid. ```jsx // valid // invalid ``` ### Hook can only be invoked from render methods This error occurs when you try to use a hook outside of a component. They are only supported inside a function component. ```jsx // Invalid, must be used inside a component const [value, setValue] = useState(0); // valid function Foo() { const [value, setValue] = useState(0); return ( ); } ``` ### Getting `vnode.[property]` is deprecated With Preact X, we did some breaking changes to our internal `vnode` shape. | Preact 8.x | Preact 10.x | | --- | --- | | `vnode.nodeName` | `vnode.type` | | `vnode.attributes` | `vnode.props` | | `vnode.children` | `vnode.props.children` | ### Found children with the same key One unique aspect about virtual-dom based libraries is that they have to detect when a child is moved around. However, to know which child is which, we need to flag them somehow. _This is only necessary when you're creating children dynamically._ ```jsx // Both children will have the same key "A"
    [{ 'A', 'A' }.map(char => (

    {char}

    ))]
    ``` The correct way to do it is to give them unique keys. In most cases, the data you're iterating over will have some form of `id`. ```jsx const persons = [ { name: 'John', age: 22 }, { name: 'Sarah', age: 24 } ]; // Somewhere later in your component
    {persons.map(({ name, age }) => { return (

    {name}, Age: {age}

    ); })}
    ; ``` --- # Source: https://preactjs.com/guide/v10/differences-to-react#features-exclusive-to-preactcompat # Differences to React Preact is not intended to be a reimplementation of React. There are differences. Many of these differences are trivial, or can be completely removed by using [preact/compat](/guide/v10/getting-started#aliasing-react-to-preact), which is a thin layer over Preact that attempts to achieve 100% compatibility with React. The reason Preact does not attempt to include every single feature of React is in order to remain **small** and **focused** - otherwise it would make more sense to simply submit optimizations to the React project, which is already a very complex and well-architected codebase. --- * [Main differences](#main-differences) * [Version Compatibility](#version-compatibility) * [Debug messages and errors](#debug-messages-and-errors) * [Features unique to Preact](#features-unique-to-preact) * [Native support for ES Modules](#native-support-for-es-modules) * [Arguments in `Component.render()`](#arguments-in-componentrender) * [Raw HTML attribute/property names](#raw-html-attributeproperty-names) * [SVG inside JSX](#svg-inside-jsx) * [Use `onInput` instead of `onChange`](#use-oninput-instead-of-onchange) * [JSX Constructor](#jsx-constructor) * [No contextTypes needed](#no-contexttypes-needed) --- ## Main differences The main difference between Preact and React is that Preact does not implement a synthetic event system for size and performance reasons. Preact uses the browser's standard `addEventListener` to register event handlers, which means event naming and behavior works the same in Preact as it does in plain JavaScript / DOM. See [MDN's Event Reference](https://developer.mozilla.org/en-US/docs/Web/Events) for a full list of DOM event handlers. Standard browser events work very similarly to how events work in React, with a few small differences. In Preact: - events don't bubble up through `` components - standard `onInput` should be used instead of React's `onChange` for form inputs (**only if `preact/compat` is not used**) - standard `onDblClick` should be used instead of React's `onDoubleClick` (**only if `preact/compat` is not used**) - `onSearch` should generally be used for ``, since the clear "x" button does not fire `onInput` in IE11 Another notable difference is that Preact follows the DOM specification more closely. Custom elements are supported like any other element, and custom events are supported with case-sensitive names (as they are in the DOM). ## Version Compatibility For both preact and [preact/compat](/guide/v10/getting-started#aliasing-react-to-preact), version compatibility is measured against the _current_ and _previous_ major releases of React. When new features are announced by the React team, they may be added to Preact's core if it makes sense given the [Project Goals](/about/project-goals). This is a fairly democratic process, constantly evolving through discussion and decisions made in the open, using issues and pull requests. > Thus, the website and documentation reflect React `15.x` through `17.x`, with some `18.x` and `19.x` additions, when discussing compatibility or making comparisons. ## Debug messages and errors Our flexible architecture allows addons to enhance the Preact experience in any way they want. One of those addons is `preact/debug` which adds [helpful warnings and errors](/guide/v10/debugging) and attaches the [Preact Developer Tools](https://preactjs.github.io/preact-devtools/) browser extension, if installed. Those guides you when developing Preact applications and make it a lot easier to inspect what's going on. You can enable them by adding the relevant import statement: ```js import 'preact/debug'; // <-- Add this line at the top of your main entry file ``` This is different from React which requires a bundler being present that strips out debugging messages at build time by checking for `NODE_ENV != "production"`. ## Features unique to Preact Preact actually adds a few convenient features inspired by work in the (P)React community: ### Native support for ES Modules Preact was built with ES Modules in mind from the beginning, and was one of the first frameworks to support them. You can load Preact via the `import` keyword directly in browsers without having it to pass through a bundler first. ### Arguments in `Component.render()` For convenience, we pass `this.props` and `this.state` to the `render()` method on class components. Take a look at this component which uses one prop and one state property. ```jsx // Works in both Preact and React class Foo extends Component { state = { age: 1 }; render() { return (
    Name: {this.props.name}, Age: {this.state.age}
    ); } } ``` In Preact this can be also written like this: ```jsx // Only works in Preact class Foo extends Component { state = { age: 1 }; render({ name }, { age }) { return (
    Name: {name}, Age: {age}
    ); } } ``` Both snippets render the exact same thing, render arguments are provided for convenience. ### Raw HTML attribute/property names Preact aims to closely match the DOM specification supported by all major browsers. When applying `props` to an element, Preact _detects_ whether each prop should be set as a property or HTML attribute. This makes it possible to set complex properties on Custom Elements, but it also means you can use attribute names like `class` in JSX: ```jsx // This:
    // ...is the same as:
    ``` Most Preact developers prefer to use `class` instead of `className` as it's shorter to write but both are supported. ### SVG inside JSX SVG is pretty interesting when it comes to the names of its properties and attributes. Some properties (and their attributes) on SVG objects are camelCased (e.g. [clipPathUnits on a clipPath element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath#Attributes)), some attributes are kebab-case (e.g. [clip-path on many SVG elements](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation)), and other attributes (usually ones inherited from the DOM, e.g. `oninput`) are all lowercase. Preact applies SVG attributes as-written. This means you can copy and paste unmodified SVG snippets right into your code and have them work out of the box. This allows greater interoperability with tools designers tend to use to generate icons or SVG illustrations. ```jsx // React // Preact (note stroke-width and stroke-linejoin) ``` If you're coming from React, you may be used to specifying all attributes in camelCase. You can continue to use always-camelCase SVG attribute names by adding [preact/compat](/guide/v10/getting-started#aliasing-react-to-preact) to your project, which mirrors the React API and normalizes these attributes. ### Use `onInput` instead of `onChange` Largely for historical reasons, the semantics of React's `onChange` event are actually the same as the `onInput` event provided by browsers, which is supported everywhere. The `input` event is the best-suited event for the majority of cases where you want to react when a form control is modified. In Preact core, `onChange` is the standard [DOM change event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event) that gets fired when an element's value is _committed_ by the user. ```jsx // React console.log(e.currentTarget.value)} /> // Preact console.log(e.currentTarget.value)} /> ``` If you're using [preact/compat](/guide/v10/getting-started#aliasing-react-to-preact), most `onChange` events are internally converted to `onInput` to emulate React's behavior. This is one of the tricks we use to ensure maximum compatibility with the React ecosystem. ### JSX Constructor JSX is a syntax extension for JavaScript that is converted to nested function calls. The idea of using these nested calls to build up tree structures long predates JSX, and was previously popularized in JavaScript by the [hyperscript](https://github.com/dominictarr/hyperscript) project. This approach has value well beyond the scope of the React ecosystem, so Preact promotes the original generalized community-standard. For a more in-depth discussion of JSX and its relationship to Hyperscript, [read this article on how JSX works](https://jasonformat.com/wtf-is-jsx). **Source:** (JSX) ```jsx Home ``` **Output:** ```js // Preact: h('a', { href: '/' }, h('span', null, 'Home')); // React: React.createElement( 'a', { href: '/' }, h('span', null, 'Home') ); ``` Ultimately, if you're looking at the generated output code for a Preact application, it's clear that a shorter un-namespaced "JSX pragma" is both easier to read _and_ more suitable for optimizations like minification. In most Preact apps you'll encounter `h()`, though it doesn't really matter which name you use since a `createElement` alias export is also provided. ### No contextTypes needed The legacy `Context` API requires Components to declare specific properties using React's `contextTypes` or `childContextTypes` in order to receive those values. Preact does not have this requirement: all Components receive all `context` properties produced by `getChildContext()` by default. --- # Source: https://preactjs.com/guide/v10/getting-started#aliasing-react-to-preact # Getting Started New to Preact? New to Virtual DOM? Check out the [tutorial](/tutorial). This guide helps you get up and running to start developing Preact apps, using 3 popular options. If you're new to Preact, we recommend starting with [Vite](#create-a-vite-powered-preact-app). --- * * * ## No build tools route Preact is packaged to be used directly in the browser, and doesn't require any build or tools: ```html ``` The primary drawback of developing this way is the lack of JSX, which requires a build step. An ergonomic and performant alternative to JSX is documented in the next section. ### Alternatives to JSX Writing raw `h` or `createElement` calls can be tedious. JSX has the advantage of looking similar to HTML, which makes it easier to understand for many developers in our experience. JSX requires a build step though, so we highly recommend an alternative called [HTM](https://github.com/developit/htm). [HTM](https://github.com/developit/htm) is a JSX-like syntax that works in standard JavaScript. Instead of requiring a build step, it uses JavaScript's own [Tagged Templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates) syntax, which was added in 2015 and is supported in [all modern browsers](https://caniuse.com/#feat=template-literals). This is an increasingly popular way to write Preact apps, since there are fewer moving parts to understand than a traditional front-end build tooling setup. ```html ``` > **Tip:** HTM also provides a convenient single-import Preact version: > > ```javascript > import { html, render } from 'https://esm.sh/htm/preact/standalone' > ``` For a more scalable solution, see [Import Maps -- Basic Usage](/guide/v10/no-build-workflows#basic-usage), and for more information on HTM, check out its [documentation](https://github.com/developit/htm). ## Create a Vite-Powered Preact App [Vite](https://vitejs.dev/) has become an incredibly popular tool for building applications across many frameworks in the past couple of years, and Preact is no exception. It's built upon popular tooling like ES modules, Rollup, and ESBuild. Vite, through our initializer or their Preact template, requires no configuration or prior knowledge to get started and this simplicity makes it a very popular way to use Preact. To get up and running with Vite quickly, you can use our initializer `create-preact`. This is an interactive command-line interface (CLI) app that can be run in the terminal on your machine. Using it, you can create a new application by running the following: ```bash npm init preact ``` This will walk you through creating a new Preact app and gives you some options such as TypeScript, routing (via `preact-iso`), and ESLint support. > **Tip:** None of these decisions need to be final, you can always add or remove them from your project later if you change your mind. ### Getting ready for development Now we're ready to start our application. To start a development server, run the following command inside your newly generated project folder: ```bash # Go into the generated project folder cd my-preact-app # Start a development server npm run dev ``` Once the server has started, it will print a local development URL to open in your browser. Now you're ready to start coding your app! ### Making a production build There comes a time when you need to deploy your app somewhere. Vite ships with a handy `build` command which will generate a highly-optimized production build. ```bash npm run build ``` Upon completion, you'll have a new `dist/` folder which can be deployed directly to a server. > For a full list of all available commands and their options, check out the [Vite CLI Documentation](https://vitejs.dev/guide/cli.html). ## Integrating Into An Existing Pipeline If you already have an existing tooling pipeline set up, it's very likely that this includes a bundler. The most popular choices are [webpack](https://webpack.js.org/), [rollup](https://rollupjs.org/), or [parcel](https://parceljs.org/). Preact works out of the box with all of them, no major changes needed! ### Setting up JSX To transpile JSX, you need a Babel plugin that converts it to valid JavaScript code. The one we all use is [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx). Once installed, you need to specify the function for JSX that should be used: ```json { "plugins": [ [ "@babel/plugin-transform-react-jsx", { "pragma": "h", "pragmaFrag": "Fragment" } ] ] } ``` > [Babel](https://babeljs.io/) has some of the best documentation out there. We highly recommend checking it out for questions surrounding Babel and how to set it up. ### Aliasing React to Preact At some point, you'll probably want to make use of the vast React ecosystem. Libraries and Components originally written for React work seamlessly with our compatibility layer. To make use of it, we need to point all `react` and `react-dom` imports to Preact. This step is called _aliasing._ > **Note:** If you're using Vite (via `@preact/preset-vite`), Preact CLI, or WMR, these aliases are automatically handled for you by default. #### Aliasing in Webpack To alias any package in Webpack, you need to add the `resolve.alias` section to your config. Depending on the configuration you're using, this section may already be present, but missing the aliases for Preact. ```js const config = { //...snip resolve: { alias: { react: 'preact/compat', 'react-dom/test-utils': 'preact/test-utils', 'react-dom': 'preact/compat', // Must be below test-utils 'react/jsx-runtime': 'preact/jsx-runtime' } } }; ``` #### Aliasing in Node When running in Node, bundler aliases (Webpack, Rollup, etc.) will not work, as can be seen in NextJS. To fix this, we can use aliases directly in our `package.json`: ```json { "dependencies": { "react": "npm:@preact/compat", "react-dom": "npm:@preact/compat" } } ``` #### Aliasing in Parcel Parcel uses the standard `package.json` file to read configuration options under an `alias` key. ```json { "alias": { "react": "preact/compat", "react-dom/test-utils": "preact/test-utils", "react-dom": "preact/compat", "react/jsx-runtime": "preact/jsx-runtime" } } ``` #### Aliasing in Rollup To alias within Rollup, you'll need to install [@rollup/plugin-alias](https://github.com/rollup/plugins/tree/master/packages/alias). The plugin will need to be placed before your [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve). ```js import alias from '@rollup/plugin-alias'; module.exports = { plugins: [ alias({ Entries: [ { find: 'react', replacement: 'preact/compat' }, { find: 'react-dom/test-utils', replacement: 'preact/test-utils' }, { find: 'react-dom', replacement: 'preact/compat' }, { find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' } ] }) ] }; ``` #### Aliasing in Jest [Jest](https://jestjs.io/) allows the rewriting of module paths similar to bundlers. These rewrites are configured using regular expressions in your Jest configuration: ```json { "moduleNameMapper": { "^react$": "preact/compat", "^react-dom/test-utils$": "preact/test-utils", "^react-dom$": "preact/compat", "^react/jsx-runtime$": "preact/jsx-runtime" } } ``` #### Aliasing in TypeScript TypeScript, even when used alongside a bundler, has its own process of resolving types. In order to ensure Preact's types are used in place of React's, you will want to add the following configuration to your `tsconfig.json` (or `jsconfig.json`): ```json { "compilerOptions": { ... "skipLibCheck": true, "baseUrl": "./", "paths": { "react": ["./node_modules/preact/compat/"], "react/jsx-runtime": ["./node_modules/preact/jsx-runtime"], "react-dom": ["./node_modules/preact/compat/"], "react-dom/*": ["./node_modules/preact/compat/*"] } } } ``` Additionally, you may want to enable `skipLibCheck` as we do in the example above. Some React libraries make use of types that may not be provided by `preact/compat` (though we do our best to fix these), and as such, these libraries could be the source of TypeScript compilation errors. By setting `skipLibCheck`, you can tell TS that it doesn't need to do a full check of all `.d.ts` files (usually these are limited to your libraries in `node_modules`) which will fix these errors. #### Aliasing with Import Maps ```html ``` See also [Import Maps -- Recipes and Common Patterns](/guide/v10/no-build-workflows#recipes-and-common-patterns) for more examples. --- # Source: https://preactjs.com/guide/v10/hooks # Hooks The Hooks API is an alternative way to write components in Preact. Hooks allow you to compose behaviors together and reuse that logic much more easily than with class components. If you've worked with class components in Preact for a while, you may be familiar with patterns like "render props" and "higher order components" that try to solve these challenges. These solutions have tended to make code harder to follow and more abstract. The hooks API makes it possible to neatly extract the logic for state and side effects, and also simplifies unit testing that logic independently from the components that rely on it. Hooks can be used in any component, and avoid many pitfalls of the `this` keyword relied on by the class components API. Instead of accessing properties from the component instance, hooks rely on closures. This makes them value-bound and eliminates a number of stale data problems that can occur when dealing with asynchronous state updates. There are two ways to import hooks: from `preact/hooks` or `preact/compat`. --- ## Introduction The easiest way to understand hooks is to compare them to equivalent class-based Components. We'll use a simple counter component as our example, which renders a number and a button that increases it by one: ```jsx class Counter extends Component { state = { value: 0 }; increment = () => { this.setState(prev => ({ value: prev.value + 1 })); }; render(props, state) { return (

    Counter: {state.value}

    ); } } ``` Now, here's an equivalent function component built with hooks: ```jsx function Counter() { const [value, setValue] = useState(0); const increment = useCallback(() => { setValue(value + 1); }, [value]); return (

    Counter: {value}

    ); } ``` At this point they seem pretty similar, however we can further simplify the hooks version. Let's extract the counter logic into a custom hook, making it easily reusable across components: ```jsx function useCounter() { const [value, setValue] = useState(0); const increment = useCallback(() => { setValue(value + 1); }, [value]); return { value, increment }; } // First counter function CounterA() { const { value, increment } = useCounter(); return (

    Counter A: {value}

    ); } // Second counter which renders a different output. function CounterB() { const { value, increment } = useCounter(); return (

    Counter B: {value}

    I'm a nice counter

    ); } ``` Note that both `CounterA` and `CounterB` are completely independent of each other. They both use the `useCounter()` custom hook, but each has its own instance of that hook's associated state. > Thinking this looks a little strange? You're not alone! > > It took many of us a while to grow accustomed to this approach. ## The dependency argument Many hooks accept an argument that can be used to limit when a hook should be updated. Preact inspects each value in a dependency array and checks to see if it has changed since the last time a hook was called. When the dependency argument is not specified, the hook is always executed. In our `useCounter()` implementation above, we passed an array of dependencies to `useCallback()`: ```jsx function useCounter() { const [value, setValue] = useState(0); const increment = useCallback(() => { setValue(value + 1); }, [value]); // <-- the dependency array return { value, increment }; } ``` Passing `value` here causes `useCallback` to return a new function reference whenever `value` changes. This is necessary in order to avoid "stale closures", where the callback would always reference the first render's `value` variable from when it was created, causing `increment` to always set a value of `1`. > This creates a new `increment` callback every time `value` changes. For performance reasons, it's often better to use a [callback](#usestate) to update state values rather than retaining the current value using dependencies. ## Stateful hooks Here we'll see how we can introduce stateful logic into functional components. Prior to the introduction of hooks, class components were required anywhere state was needed. ### useState This hook accepts an argument, this will be the initial state. When invoked this hook returns an array of two variables. The first being the current state and the second being the setter for our state. Our setter behaves similar to the setter of our classic state. It accepts a value or a function with the currentState as argument. When you call the setter and the state is different, it will trigger a rerender starting from the component where that useState has been used. ```jsx import { useState } from 'preact/hooks'; const Counter = () => { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(count + 1); }); // You can also pass a callback to the setter const decrement = useCallback(() => { setCount(currentCount => currentCount - 1); }); return (

    Count: {count}

    ); }; ``` > When our initial state is expensive it's better to pass a function instead of a value. ### useReducer The `useReducer` hook has a close resemblance to [redux](https://redux.js.org/). Compared to [useState](#usestate) it's easier to use when you have complex state logic where the next state depends on the previous one. ```jsx 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 Counter() { // Returns the current state and a dispatch function to // trigger an action const [count, dispatch] = useReducer(reducer, initialState); return (
    {count}
    ); } ``` ## Memoization In UI programming there is often some state or result that's expensive to calculate. Memoization can cache the results of that calculation allowing it to be reused when the same input is used. ### useMemo With the `useMemo` hook we can memoize the results of that computation and only recalculate it when one of the dependencies changes. ```jsx const memoized = useMemo( () => expensive(a, b), // Only re-run the expensive function when any of these // dependencies change [a, b] ); ``` > Don't run any effectful code inside `useMemo`. Side-effects belong in `useEffect`. ### useCallback The `useCallback` hook can be used to ensure that the returned function will remain referentially equal for as long as no dependencies have changed. This can be used to optimize updates of child components when they rely on referential equality to skip updates (e.g. `shouldComponentUpdate`). ```jsx const onClick = useCallback(() => console.log(a, b), [a, b]); ``` > Fun fact: `useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`. ## Refs **Ref**erences are stable, local values that persist across rerenders but don't cause rerenders themselves. See [Refs](/guide/v10/refs) for more information & examples. ### useRef To create a stable reference to a DOM node or a value that persists between renders, we can use the `useRef` hook. It works similarly to [createRef](/guide/v10/refs#createref). ```jsx function Foo() { // Initialize useRef with an initial value of `null` const input = useRef(null); const onClick = () => input.current && input.current.focus(); return ( <> ); } ``` > Be careful not to confuse `useRef` with `createRef`. ### useImperativeHandle To mutate a ref that is passed into a child component we can use the `useImperativeHandle` hook. It takes three arguments: the ref to mutate, a function to execute that will return the new ref value, and a dependency array to determine when to rerun. ```jsx function MyInput({ inputRef }) { const ref = useRef(null); useImperativeHandle( inputRef, () => { return { // Only expose `.focus()`, don't give direct access to the DOM node focus() { ref.current.focus(); } }; }, [] ); return ( ); } function App() { const inputRef = useRef(null); const handleClick = () => { inputRef.current.focus(); }; return (
    ); } ``` ## useContext To access context in a functional component we can use the `useContext` hook, without any higher-order or wrapper components. The first argument must be the context object that's created from a `createContext` call. ```jsx const Theme = createContext('light'); function DisplayTheme() { const theme = useContext(Theme); return

    Active theme: {theme}

    ; } // ...later function App() { return ( ); } ``` ## Side-Effects Side-Effects are at the heart of many modern Apps. Whether you want to fetch some data from an API or trigger an effect on the document, you'll find that the `useEffect` fits nearly all your needs. It's one of the main advantages of the hooks API, that it reshapes your mind into thinking in effects instead of a component's lifecycle. ### useEffect As the name implies, `useEffect` is the main way to trigger various side-effects. You can even return a cleanup function from your effect if one is needed. ```jsx useEffect(() => { // Trigger your effect return () => { // Optional: Any cleanup code }; }, []); ``` We'll start with a `Title` component which should reflect the title to the document, so that we can see it in the address bar of our tab in our browser. ```jsx function PageTitle(props) { useEffect(() => { document.title = props.title; }, [props.title]); return

    {props.title}

    ; } ``` The first argument to `useEffect` is an argument-less callback that triggers the effect. In our case we only want to trigger it, when the title really has changed. There'd be no point in updating it when it stayed the same. That's why we're using the second argument to specify our [dependency-array](#the-dependency-argument). But sometimes we have a more complex use case. Think of a component which needs to subscribe to some data when it mounts and needs to unsubscribe when it unmounts. This can be accomplished with `useEffect` too. To run any cleanup code we just need to return a function in our callback. ```jsx // Component that will always display the current window width function WindowWidth(props) { const [width, setWidth] = useState(0); function onResize() { setWidth(window.innerWidth); } useEffect(() => { window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, []); return

    Window width: {width}

    ; } ``` > The cleanup function is optional. If you don't need to run any cleanup code, you don't need to return anything in the callback that's passed to `useEffect`. ### useLayoutEffect Similar to [`useEffect`](#useeffect), `useLayoutEffect` is used to trigger side-effects but it will do so as soon as the component is diffed and before the browser has a chance to repaint. Commonly used for measuring DOM elements, this allows you to avoid flickering or pop-in that may occur if you use `useEffect` for such tasks. ```jsx import { useLayoutEffect, useRef } from 'preact/hooks'; function App() { const hintRef = useRef(null); useEffect(() => { const hintWidth = hintRef.current.getBoundingClientRect().width; // We might use this width to position and center the hint on the screen, like so: hintRef.current.style.left = `${((window.innerWidth - hintWidth) / 2}px`; }, []); return (

    This is a hint

    ); } ``` ### useErrorBoundary Whenever a child component throws an error you can use this hook to catch it and display a custom error UI to the user. ```jsx // error = The error that was caught or `undefined` if nothing errored. // resetError = Call this function to mark an error as resolved. It's // up to your app to decide what that means and if it is possible // to recover from errors. const [error, resetError] = useErrorBoundary(); ``` For monitoring purposes it's often incredibly useful to notify a service of any errors. For that we can leverage an optional callback and pass that as the first argument to `useErrorBoundary`. ```jsx const [error] = useErrorBoundary(error => callMyApi(error.message)); ``` A full usage example may look like this: ```jsx const App = props => { const [error, resetError] = useErrorBoundary(error => callMyApi(error.message) ); // Display a nice error message if (error) { return (

    {error.message}

    ); } else { return (
    {props.children}
    ); } }; ``` > If you've been using the class based component API in the past, then this hook is essentially an alternative to the [componentDidCatch](/guide/v10/whats-new/#componentdidcatch) lifecycle method. This hook was introduced with Preact 10.2.0. ## Utility hooks ### useId This hook will generate a unique identifier for each invocation and guarantees that these will be consistent when rendering both [on the server](/guide/v10/server-side-rendering) and the client. A common use case for consistent IDs are forms, where `