API 参考
此页面作为对所有导出函数的快速概述。
组件
Component
是一个基类,可以扩展它来创建有状态的 Preact 组件。
组件不是直接实例化的,而是由渲染器管理并根据需要创建。
import { Component } from 'preact';
class MyComponent extends Component {
// (see below)
}
Component.render(props, state)
所有组件都必须提供一个 render()
函数。render 函数传递组件的当前 props 和 state,并且应该返回一个虚拟 DOM 元素(通常是 JSX “元素”)、一个数组或 null
。
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>;
}
}
要了解有关组件及其如何使用的更多信息,请查看 组件文档。
render()
render(virtualDom, containerNode, [replaceNode])
将虚拟 DOM 元素渲染到父 DOM 元素 containerNode
中。不返回任何内容。
// 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>
在 REPL 中运行如果提供了可选的 replaceNode
参数,它必须是 containerNode
的子级。Preact 不会推断从哪里开始渲染,而是使用其差异算法更新或替换传递的元素。
⚠️
replaceNode
参数将随 Preactv11
删除。它引入了太多边缘情况和错误,需要在 Preact 的其余源代码中加以考虑。出于历史原因,我们保留了此部分,但我们不建议任何人使用第三个replaceNode
参数。
// DOM tree before render:
// <div id="container">
// <div>bar</div>
// <div id="target">foo</div>
// </div>
import { render } from 'preact';
const Foo = () => <div id="target">BAR</div>;
render(
<Foo />,
document.getElementById('container'),
document.getElementById('target')
);
// After render:
// <div id="container">
// <div>bar</div>
// <div id="target">BAR</div>
// </div>
第一个参数必须是有效的虚拟 DOM 元素,它表示组件或元素。在传递组件时,让 Preact 进行实例化而不是直接调用组件非常重要,这会以意外的方式中断
const App = () => <div>foo</div>;
// DON'T: Invoking components directly breaks hooks and update ordering:
render(App(), rootElement); // ERROR
render(App, rootElement); // ERROR
// DO: Passing components using h() or JSX allows Preact to render correctly:
render(h(App), rootElement); // success
render(<App />, rootElement); // success
hydrate()
如果您已预渲染或服务器端渲染应用程序到 HTML,Preact 可以在浏览器中加载时绕过大部分渲染工作。这可以通过从 render()
切换到 hydrate()
来启用,它在仍附加事件侦听器并设置组件树的同时跳过大部分差异。这仅在与预渲染或服务器端渲染结合使用时才有效。
import { hydrate } from 'preact';
const Foo = () => <div>foo</div>;
hydrate(<Foo />, document.getElementById('container'));
在 REPL 中运行h() / createElement()
h(type, props, ...children)
返回具有给定 props
的虚拟 DOM 元素。虚拟 DOM 元素是应用程序 UI 层次结构中节点的轻量级描述,本质上是 { type, props }
形式的对象。
在 type
和 props
之后,任何剩余参数都将收集到 children
属性中。子项可以是以下任何一项
- 标量值(字符串、数字、布尔值、null、undefined 等)
- 嵌套的虚拟 DOM 元素
- 上述内容的无限嵌套数组
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
此辅助函数将 props.children
值转换为扁平数组,无论其结构或嵌套如何。如果 props.children
已经是数组,则返回副本。此函数在 props.children
可能不是数组的情况下很有用,这可能发生在 JSX 中静态和动态表达式的某些组合中。
对于具有单个子项的虚拟 DOM 元素,props.children
是对子项的引用。当有多个子项时,props.children
始终是数组。toChildArray
帮助器提供了一种一致处理所有情况的方法。
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)
此函数允许您创建虚拟 DOM 元素的浅表副本。它通常用于添加或覆盖元素的 props
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
请参阅上下文文档中的部分。
createRef
提供了一种在元素或组件呈现后对其进行引用的方法。
有关更多详细信息,请参阅引用文档。
Fragment
一种特殊类型的组件,它可以有子项,但不会呈现为 DOM 元素。片段可以返回多个同级子项,而无需将它们包装在 DOM 容器中
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>
在 REPL 中运行