Skip to content

Start v11 docs #1278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions content/en/guide/v11/api-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
name: API Reference
description: 'Learn more about all exported functions of the Preact module'
---

# API Reference

This page serves as a quick overview over all exported functions.

---

<div><toc></toc></div>

---

## Component

`Component` is a base class that can be extended to create stateful Preact components.

Rather than being instantiated directly, Components are managed by the renderer and created as-needed.

```js
import { Component } from 'preact';

class MyComponent extends Component {
// (see below)
}
```

### Component.render(props, state)

All components must provide a `render()` function. The render function is passed the component's current props and state, and should return a Virtual DOM Element (typically a JSX "element"), an Array, or `null`.

```jsx
import { Component } from 'preact';

class MyComponent extends Component {
render(props, state) {
// props is the same as this.props
// state is the same as this.state

return <h1>Hello, {props.name}!</h1>;
}
}
```

To learn more about components and how they can be used, check out the [Components Documentation](/guide/v11/components).

## render()

`render(virtualDom, containerNode)`

Render a Virtual DOM Element into a parent DOM element `containerNode`. Does not return anything.

```jsx
// --repl
// DOM tree before render:
// <div id="container"></div>

import { render } from 'preact';

const Foo = () => <div>foo</div>;

render(<Foo />, document.getElementById('container'));

// After render:
// <div id="container">
// <div>foo</div>
// </div>
```

## hydrate()

If you've already pre-rendered or server-side-rendered your application to HTML, Preact can bypass most rendering work when loading in the browser. This can be enabled by switching from `render()` to `hydrate()`, which skips most diffing while still attaching event listeners and setting up your component tree. This works only when used in conjunction with pre-rendering or [Server-Side Rendering](/guide/v11/server-side-rendering).

```jsx
// --repl
import { hydrate } from 'preact';

const Foo = () => <div>foo</div>;
hydrate(<Foo />, document.getElementById('container'));
```

## h() / createElement()

`h(type, props, ...children)`

Returns a Virtual DOM Element with the given `props`. Virtual DOM Elements are lightweight descriptions of a node in your application's UI hierarchy, essentially an object of the form `{ type, props }`.

After `type` and `props`, any remaining parameters are collected into a `children` property.
Children may be any of the following:

- Scalar values (string, number, boolean, null, undefined, etc)
- Nested Virtual DOM Elements
- Infinitely nested Arrays of the above

```js
import { h } from 'preact';

h('div', { id: 'foo' }, 'Hello!');
// <div id="foo">Hello!</div>

h('div', { id: 'foo' }, 'Hello', null, ['Preact!']);
// <div id="foo">Hello Preact!</div>

h(
'div',
{ id: 'foo' },
h('span', null, 'Hello!')
);
// <div id="foo"><span>Hello!</span></div>
```

## toChildArray

This helper function converts a `props.children` value to a flattened Array regardless of its structure or nesting. If `props.children` is already an array, a copy is returned. This function is useful in cases where `props.children` may not be an array, which can happen with certain combinations of static and dynamic expressions in JSX.

For Virtual DOM Elements with a single child, `props.children` is a reference to the child. When there are multiple children, `props.children` is always an Array. The `toChildArray` helper provides a way to consistently handle all cases.

```jsx
import { toChildArray } from 'preact';

function Foo(props) {
const count = toChildArray(props.children).length;
return <div>I have {count} children</div>;
}

// props.children is "bar"
render(
<Foo>bar</Foo>,
container
);

// props.children is [<p>A</p>, <p>B</p>]
render(
<Foo>
<p>A</p>
<p>B</p>
</Foo>,
container
);
```

## cloneElement

`cloneElement(virtualElement, props, ...children)`

This function allows you to create a shallow copy of a Virtual DOM Element.
It's generally used to add or overwrite `props` of an element:

```jsx
function Linkout(props) {
// add target="_blank" to the link:
return cloneElement(props.children, { target: '_blank' });
}
render(<Linkout><a href="/">home</a></Linkout>);
// <a href="/" target="_blank">home</a>
```

## createContext

See the section in the [Context documentation](/guide/v11/context#createcontext).

## createRef

Provides a way to reference an element or component once it has been rendered.

See the [References documentation](/guide/v11/refs#createref) for more details.

## Fragment

A special kind of component that can have children, but is not rendered as a DOM element.
Fragments make it possible to return multiple sibling children without needing to wrap them in a DOM container:

```jsx
// --repl
import { Fragment, render } from 'preact';

render(
<Fragment>
<div>A</div>
<div>B</div>
<div>C</div>
</Fragment>,
document.getElementById('container')
);
// Renders:
// <div id="container>
// <div>A</div>
// <div>B</div>
// <div>C</div>
// </div>
```
205 changes: 205 additions & 0 deletions content/en/guide/v11/components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
name: Components
description: 'Components are the heart of any Preact application. Learn how to create them and use them to compose UIs together'
---

# 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.

---

<div><toc></toc></div>

---

## 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
// --repl
import { render } from 'preact';

// --repl-before
function MyComponent(props) {
return <div>My name is {props.name}.</div>;
}

// Usage
const App = <MyComponent name="John Doe" />;

// Renders: <div>My name is John Doe.</div>
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/v11/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 `<Clock>` that displays the current time:

```jsx
// --repl
import { Component, render } from 'preact';

// --repl-before
class Clock extends Component {

constructor() {
super();
this.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 <span>{time}</span>;
}
}
// --repl-after
render(<Clock />, document.getElementById('app'));
```

### Lifecycle Methods

In order to have the clock's time update every second, we need to know when `<Clock>` 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 |
|-----------------------------|--------------------------------------------------|
| `componentDidMount()` | after the component gets mounted to the DOM
| `componentWillUnmount()` | prior to removal from the DOM
| `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
| `getSnapshotBeforeUpdate(prevProps, prevState)` | called just before `render()`. 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
// --repl
import { Component, render } from 'preact';
// --repl-before
class ErrorBoundary extends Component {
constructor() {
super();
this.state = { errored: false };
}

static getDerivedStateFromError(error) {
return { errored: true };
}

componentDidCatch(error, errorInfo) {
errorReportingService(error, errorInfo);
}

render(props, state) {
if (state.errored) {
return <p>Something went badly wrong</p>;
}
return props.children;
}
}
// --repl-after
render(<ErrorBoundary />, document.getElementById('app'));
```

## 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
// --repl
import { Fragment, render } from 'preact';

function TodoItems() {
return (
<Fragment>
<li>A</li>
<li>B</li>
<li>C</li>
</Fragment>
)
}

const App = (
<ul>
<TodoItems />
<li>D</li>
</ul>
);

render(App, container);
// Renders:
// <ul>
// <li>A</li>
// <li>B</li>
// <li>C</li>
// <li>D</li>
// </ul>
```

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 = <Fragment>foo</Fragment>;
// ...is the same as this:
const Bar = <>foo</>;
```

You can also return arrays from your components:

```jsx
function Columns() {
return [
<td>Hello</td>,
<td>World</td>
];
}
```

Don't forget to add keys to `Fragments` if you create them in a loop:

```jsx
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
// Without a key, Preact has to guess which elements have
// changed when re-rendering.
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>
);
}
```
Loading
Loading