|
| 1 | +--- |
| 2 | +title: API 参考 |
| 3 | +description: 了解 Preact 模块导出的所有函数 |
| 4 | +--- |
| 5 | + |
| 6 | +# API 参考 |
| 7 | + |
| 8 | +此页为您提供所有导出函数的速查表。 |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +<toc></toc> |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## Component |
| 17 | + |
| 18 | +`Component` 是用于创建有状态 Preact 组件的基类。 |
| 19 | + |
| 20 | +渲染器会自动管理并按需创建组件,不会直接实例化。 |
| 21 | + |
| 22 | +```js |
| 23 | +import { Component } from 'preact'; |
| 24 | + |
| 25 | +class MyComponent extends Component { |
| 26 | + // (见下) |
| 27 | +} |
| 28 | +``` |
| 29 | + |
| 30 | +### Component.render(props, state) |
| 31 | + |
| 32 | +所有组件必须提供 `render()` 函数,其参数为组件的当前属性 (props) 与状态 (state),返回值则是虚拟 DOM 元素 (JSX 元素)、Array,或 `null`。 |
| 33 | + |
| 34 | +```jsx |
| 35 | +import { Component } from 'preact'; |
| 36 | + |
| 37 | +class MyComponent extends Component { |
| 38 | + render(props, state) { |
| 39 | + // props 等同于 this.props |
| 40 | + // state 等同于 this.state |
| 41 | + |
| 42 | + return <h1>Hello, {props.name}!</h1>; |
| 43 | + } |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +请参阅[组件文档](/guide/v10/components)来了解其概念及使用方法。 |
| 48 | + |
| 49 | +## render() |
| 50 | + |
| 51 | +`render(virtualDom, containerNode)` |
| 52 | + |
| 53 | +将虚拟 DOM 元素渲染为父 DOM 元素的 `containerNode`,无返回值。 |
| 54 | + |
| 55 | +```jsx |
| 56 | +// --repl |
| 57 | +// 渲染前的 DOM 树: |
| 58 | +// <div id="container"></div> |
| 59 | + |
| 60 | +import { render } from 'preact'; |
| 61 | + |
| 62 | +const Foo = () => <div>foo</div>; |
| 63 | + |
| 64 | +render(<Foo />, document.getElementById('container')); |
| 65 | + |
| 66 | +// 渲染后: |
| 67 | +// <div id="container"> |
| 68 | +// <div>foo</div> |
| 69 | +// </div> |
| 70 | +``` |
| 71 | + |
| 72 | +首个参数必须为有效的虚拟 DOM 元素,可为组件或是普通元素。当您传入组件时,您需要让 Preact 实例化它,而不是直接调用组件。否则,这会出现问题: |
| 73 | + |
| 74 | +```jsx |
| 75 | +const App = () => <div>foo</div>; |
| 76 | + |
| 77 | +// 不要:直接调用组件会破坏钩子和更新顺序: |
| 78 | +render(App(), rootElement); // 错误 |
| 79 | +render(App, rootElement); // 错误 |
| 80 | + |
| 81 | +// 要:使用 h() 或 JSX 向 Preact 传入组件才能正确渲染: |
| 82 | +render(h(App), rootElement); // 成功 |
| 83 | +render(<App />, rootElement); // 成功 |
| 84 | +``` |
| 85 | + |
| 86 | +## hydrate() |
| 87 | + |
| 88 | +若您已经通过预渲染或服务端渲染的方式将应用转换为 HTML,Preact 可以在浏览器加载时跳过大部分渲染流程。您可以通过将 `render()` 替换为 `hydrate()` 的方式跳过大部分差异对比流程,而事件监听器和组件树仍能正常使用。此函数仅能与预渲染或[服务端渲染](/guide/v10/server-side-rendering)搭配使用。 |
| 89 | + |
| 90 | +```jsx |
| 91 | +// --repl |
| 92 | +import { hydrate } from 'preact'; |
| 93 | + |
| 94 | +const Foo = () => <div>foo</div>; |
| 95 | +hydrate(<Foo />, document.getElementById('container')); |
| 96 | +``` |
| 97 | + |
| 98 | +## h() / createElement() |
| 99 | + |
| 100 | +`h(type, props, ...children)` |
| 101 | + |
| 102 | +返回属性为 `props` 的虚拟 DOM 元素。虚拟 DOM 属性是您应用 UI 树中的轻量级节点描述,是形似 `{ type, props }` 的对象。 |
| 103 | + |
| 104 | +在 `type` 和 `props` 参数之后,其他所有参数均会转化为 `children` 子元素属性。 |
| 105 | +子元素可以为: |
| 106 | + |
| 107 | +- 标量值 (string、number、boolean、null、undefined 等等) |
| 108 | +- 嵌套的虚拟 DOM 元素 |
| 109 | +- 无限嵌套的上述类型 Array |
| 110 | + |
| 111 | +```js |
| 112 | +import { h } from 'preact'; |
| 113 | + |
| 114 | +h('div', { id: 'foo' }, 'Hello!'); |
| 115 | +// <div id="foo">Hello!</div> |
| 116 | + |
| 117 | +h('div', { id: 'foo' }, 'Hello', null, ['Preact!']); |
| 118 | +// <div id="foo">Hello Preact!</div> |
| 119 | + |
| 120 | +h('div', { id: 'foo' }, h('span', null, 'Hello!')); |
| 121 | +// <div id="foo"><span>Hello!</span></div> |
| 122 | +``` |
| 123 | + |
| 124 | +## toChildArray |
| 125 | + |
| 126 | +此辅助函数将 `props.children` 值转化为一维 Array 数组。若 `props.children` 已是数组,此函数将返回其复制值。此函数适合在 `props.children` 里同时存在 JSX 静态和动态表达式时使用。 |
| 127 | + |
| 128 | +对于只有一个子元素的虚拟 DOM 元素而言,`props.children` 是其子元素的引用。当有多个子元素存在时,`props.children` 是一个 Array。`toChildArray` 辅助函数能帮您处理所有情况,返回统一的值。 |
| 129 | + |
| 130 | +```jsx |
| 131 | +import { toChildArray } from 'preact'; |
| 132 | + |
| 133 | +function Foo(props) { |
| 134 | + const count = toChildArray(props.children).length; |
| 135 | + return <div>I have {count} children</div>; |
| 136 | +} |
| 137 | + |
| 138 | +// props.children 是 "bar" |
| 139 | +render(<Foo>bar</Foo>, container); |
| 140 | + |
| 141 | +// props.children 是 [<p>A</p>, <p>B</p>] |
| 142 | +render( |
| 143 | + <Foo> |
| 144 | + <p>A</p> |
| 145 | + <p>B</p> |
| 146 | + </Foo>, |
| 147 | + container |
| 148 | +); |
| 149 | +``` |
| 150 | + |
| 151 | +## cloneElement |
| 152 | + |
| 153 | +`cloneElement(virtualElement, props, ...children)` |
| 154 | + |
| 155 | +此函数用于创建虚拟 DOM 元素的浅拷贝,通常在添加或覆盖组件 `props` 属性时使用: |
| 156 | + |
| 157 | +```jsx |
| 158 | +function Linkout(props) { |
| 159 | + // 为链接添加 target="_blank": |
| 160 | + return cloneElement(props.children, { target: '_blank' }); |
| 161 | +} |
| 162 | +render( |
| 163 | + <Linkout> |
| 164 | + <a href="/">home</a> |
| 165 | + </Linkout> |
| 166 | +); |
| 167 | +// <a href="/" target="_blank">home</a> |
| 168 | +``` |
| 169 | + |
| 170 | +## createContext |
| 171 | + |
| 172 | +参见[上下文文档一节](/guide/v10/context#createcontext)。 |
| 173 | + |
| 174 | +## createRef |
| 175 | + |
| 176 | +提供渲染后引用元素或组件的方式。 |
| 177 | + |
| 178 | +参见[引用文档](/guide/v10/refs#createref)以了解详情。 |
| 179 | + |
| 180 | +## Fragment |
| 181 | + |
| 182 | +一种可包含子元素的特殊组件,但不渲染为 DOM 元素。片段无需您将多个子元素包裹在 DOM 容器中就能返回多个元素: |
| 183 | + |
| 184 | +```jsx |
| 185 | +// --repl |
| 186 | +import { Fragment, render } from 'preact'; |
| 187 | + |
| 188 | +render( |
| 189 | + <Fragment> |
| 190 | + <div>A</div> |
| 191 | + <div>B</div> |
| 192 | + <div>C</div> |
| 193 | + </Fragment>, |
| 194 | + document.getElementById('container') |
| 195 | +); |
| 196 | +// 渲染结果: |
| 197 | +// <div id="container> |
| 198 | +// <div>A</div> |
| 199 | +// <div>B</div> |
| 200 | +// <div>C</div> |
| 201 | +// </div> |
| 202 | +``` |
0 commit comments