2

原文: https://github.com/dekujs/deku/blob/master/docs/guides/components.md


Components 是 UI 当中重用的部分.
可以把 component 认为是 select 元素那样可以复合的自定义元素.

每个生命周期的钩子可以定义一个函数, 用来操作 state, 会偶尔返回需要的数据.

component 只不过是对象, 对象上有函数和属性.
其中不存储任何的 state, 也没有到处用的 this.

jsexport let Button = {
  render (component) {
    let {props,state} = component
    return <div>{props.children}</div>
  }
}

使用模块只需要引用一下, 然后挂载:

jsimport {Button} from './button.js'
import {element,tree,render} from 'deku'

let app = tree(
  <Button>Hello!</Button>
)

render(app, document.body)

首先, 引入 button 对象, 然后, 用 deku 的函数创建应用.
然后, 把元素挂在到应用上. 然后, 用 render 函数渲染到 DOM 当中.

所有可用的 component 属性包括:

定义 component 名称用于调试

jsexport let name = 'My Component'

initialState

获取 component 初始状态

jsexport function initialState (props) {
  return {
    open: true
  }
}

defaultProps

默认 props 定义好以后在所有的实例当中都有效

jsexport let defaultProps = {
  style: 'round' 
}

beforeMount

这个钩子在客户端和服务端都会调用
Client: Yes
Server: Yes

jsexport function beforeMount (component) {
  let {props, state, id} = component
}

shouldUpdate

每次 update 都会调用, 用于跳过渲染提高 component 性能
Client: Yes
Server: No

jsexport function shouldUpdate (component, nextProps, nextState) {
  let {props, state, id} = component
  return true
}

beforeRender

每次渲染前都会调用, 客户端和服务端都会
- 根据下一个 props 更新 stream/emitter

Client: Yes
Server: Yes

jsexport function beforeRender (component) {
  let {props, state, id} = component
}

beforeUpdate

初次渲染不会调用, 只是在更新时调用
用例:
- 根据下一个 props 更新 stream/emitter

Client: Yes
Server: No

jsexport function beforeUpdate (component, nextProps, nextState) {
  let {props, state, id} = component
}

render

渲染 component. 传进一个 setState 可用在 sub-component 里调用
注意未来可能会改
Client: Yes
Server: Yes

jsexport function render (component, setState) {
  let {props, state, id} = component
  return <div></div>
}

afterRender

每次渲染后调用, 包括第一次
它在初次渲染时也调用, 这比 afterUpdate 要好
这让我们按照每次渲染去考虑问题, 而不是生命周期
在这里不允许更新 state, 因为很可能导致你根据 DOM 来修改状态
用例:
- 基于最新的 state 更新 DOM, 比如, 动画, 事件处理

Client: Yes
Server: No

jsexport function afterRender (component, el) {
  let {props, state, id} = component
}

afterUpdate

不在初次渲染是调用, 在其他每次渲染时调用
用例:
- 根据上一个 state 的 transition 修改 state
- state 被修改之后调用

Client: Yes
Server: No

jsexport function afterUpdate (component, prevProps, prevState, setState) {
  let {props, state, id} = component
}

afterMount

只在 component 初次渲染后调用, 只会调用一次
用例:
- 统计追踪
- 加载初始数据
- 马上更新需要的状态, 比如, open/close
- 在 window/document 上添加 DOM 事件处理器
- 移动 DOM 当中的元素, 比如, dislog 移动到根节点
- 聚焦到元素

Client: Yes
Server: No

jsexport function afterMount (component, el, setState) {
  let {props, state, id} = component
}

beforeUnmount

只会在元素被移除时调用一次, 用于 component 卸载之后的清除
用例:
- 解绑 window/document 的事件处理器
- 在 component 卸载后对 DOM 做任何修改
- 解绑事件 emitters
- Disconnect streams

Client: Yes
Server: No

jsexport function beforeUnmount (component, el) {
  let {props, state, id} = component
}

题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者