Skip to main content
Version: 3.x

函数式组件

普通函数式组件

v1.3.0-beta.0 起支持

定义一个函数式组件非常简单:

function Welcome(props) {
return <View>Hello, {props.name}</View>;
}

这个函数接受一个参数 props,并且返回的是一个 JSX 元素。这样的函数就是函数式组件。相对于的 ES6 Class 组件是:

class Welcome extends React.Component {
render() {
return <View>Hello, {this.props.name}</View>;
}
}

在 Taro 中使用函数式组件有以下限制:

  1. 函数的命名需要遵循帕斯卡式命名法
  2. 一个文件中只能定义一个普通函数式组件或一个 Class 组件

类函数式组件

v1.3.0-beta.0 起支持

由于一个文件不能定义两个组件,但有时候我们需要组件内部的抽象组件,这时类函数式组件就是你想要答案。假设我们有一个 Class 组件,它包括了一个 Header 一个 Footer,我们可以这样定义:

class SomePage extends Taro.Component {
renderHeader () {
const { header } = this.state
return <View>{header}</View>
}

renderFooter (footer) {
return <View>{footer}</View>
}

render () {
return (
<View>
{this.renderHeader()}
{...}
{this.renderFooter('footer')}
</View>
)
}
}

renderHeaderrenderFooter 函数中,我们可以访问类的 this,也可以传入不限量的参数,这类型的函数也可以调用无限次数。但这样的写法也存在一些限制:

  1. 函数的命名必须以 render 开头,render 后的第一个字母需要大写
  2. 函数的参数不得传入 JSX 元素或 JSX 元素引用
  3. 函数不能递归地调用自身

形如 renderHeader 这样的函数在小程序中会编译成 template,而小程序的 template 是无法做到递归调用自身的。当你有这样的需求时,可以新建两个一模一样的组件和文件:ComponentA 和 ComponentB,在 ComponentA 中调用 ComponentB,在 ComponentB 中调用 ComponnetA。

闭包函数式组件

v1.3.0-beta.2 起支持

在一个普通的函数式组件中,我们需要一个另外的抽象组件多次调用,同时我们还希望这个抽象组件能访问到我们当前作用域的值,这时候我们就需要闭包函数式组件:

function Header ({ user }) {
const name = user.name
const renderTitle = () => {
// renderTitle 每次都能获取到当前作用域 `name` 的值
return <View>Welcome, {name}</View>
}
return (
<View>
{/* 重要人士我们要欢迎他三次 */ }
{renderTitle()}
{renderTitle()}
{renderTitle()}
</View>
)
}

闭包函数式组件遵循所有类函数式的限制,包括命名,传参,调用,并且它只能在一个普通函数式组件或类函数式组件以及 Taro.Componentrender 函数中定义及调用。

一般情况下只建议在普通函数式组件中使用闭包函数式组件,而在 Taro.Component 中可以显式地定义一个类函数式组件和它的参数和签名,这样函数的作用域更为清晰也更易维护。