Taro开发中的注意事项

微信小程序开发工具的配置

由于 Taro 编译后的代码已经经过了转义和压缩,因此还需要注意微信开发者工具的项目设置

  • 设置关闭 ES6 转 ES5 功能
  • 设置关闭上传代码时样式自动补全
  • 设置关闭代码压缩上传

Taro与React的差异

部分React能正常使用的代码在Taro无法运行

1.不支持在 render() 之外的方法中定义 JSX

只在 render 方法中定义JSX

以下方法均会报错
class App extends Component {
  _render() {
    return <View />
  }
}

class App extends Component {
  renderHeader(showHeader) {
    return showHeader && <Header />
  }
}

正确方法
class App extends Component {

  render () {
    const showHeader  = this.state.showHeader
    const header = showHeader && <Header />
    return (
      <View>
        {header}
      </View>
    )
  }
}

2.不能在包含 JSX 元素的 map 循环中使用 if 表达式

尽量在 map 循环中使用条件表达式或逻辑表达式。

无效情况
numbers.map((number) => {
  let element = null
  const isOdd = number % 2
  if (isOdd) {
    element = <Custom />
  }
  return element
})
正确方法
numbers.map((number) => {
  const isOdd = number % 2
  return isOdd ? <Custom /> : null
})

3.不能使用 Array.map 之外的方法操作 JSX 数组

既对于JSX数组,只有map方法会生效,其余的入foreach,filter,find等数组方法都无效,所以先处理好需要遍历的数组,然后再用处理好的数组调用 map 方法。

numbers.filter(isOdd).map((number) => <View />)

for (let index = 0; index < array.length; index++) {
  // do you thing with array
}

const element = array.map(item => {
  return <View />
})

4.不能在 JSX 参数中使用匿名函数

使用bind或类参数绑定函数

错误
<View onClick={() => this.handleClick()} />
正确方法
<View onClick={this.props.hanldeClick.bind(this)} />

5.不能在 JSX 参数中使用对象展开符

Taro中,JSX不支持...展开参数,只能自行赋值

错误
<CustomView {...this.props} />
正确方法
<CustomView id={this.props.id} title={this.props.title}} />

6.不允许在 JSX 参数(props)中传入 JSX 元素

Taro不支持内置组件化功能(slot),只能通过 props 传值在 JSX 模板中预先判定显示内容,或通过 props.children 来嵌套子组件。

7.不支持无状态组件(Stateless Component)

由于微信的 template 能力有限,不支持动态传值和函数,Taro 暂时只支持一个文件只定义一个组件

错误
const Test = () => {
  return <View />
}
const Test = function () {
  return <View />
}

正确方法
class App extends Component {
  render () {
    return (
      <View />
    )
  }
}

命名规范

  • 方法名不能含有数字
  • 方法名不能以下划线开头或结尾
  • 方法名的长度不能大于 20
    否则代码在微信小程序编译后会报错

推荐的编码方式

  • 给组件设置 defaultProps
  • 组件传递自定义函数属性名以 on 开头,以内置组件方法保持一致
  • 小程序端不要在组件中打印传入的函数
  • 小程序端不要将在模板中用到的数据设置为 undefined(可以用Null代替)
  • 小程序端不要在组件中打印 this.props.children
  • 不要以 id、class、style 作为自定义组件的属性与内部 state 的名称,因为这些属性名在微信小程序中会丢失。
  • 不要在 state 与 props 上用同名的字段,因为这些被字段在微信小程序中都会挂在 data 上
  • 由于微信小程序里页面在 onLoad 时才能拿到页面的路由参数,而页面 onLoad 前组件都已经 attached 了。因此页面的 componentWillMount 可能会与预期不太一致
  • 在 Taro 编译到小程序端后,组件的 constructor 与 render 默认会多调用一次,表现得与 React 不太一致, 所以,在编码时,需要在处理数据的时候做一些容错处理,这样可以避免在 constructor 与 render 提前调用时出现由于没有数据导致出错的情况
  • JS 编码必须用单引号
  • 不要以解构的方式来获取通过 env 配置的 process.env 环境变量,请直接以完整书写的方式 process.env.NODE_ENV 来进行使用

预加载

在微信小程序中,从调用 Taro.navigateTo、Taro.redirectTo 或 Taro.switchTab 后,到页面触发 componentWillMount 会有一定延时。因此一些网络请求可以提前到发起跳转前一刻去请求。

Taro 提供了 componentWillPreload 钩子,它接收页面跳转的参数作为参数。可以把需要预加载的内容通过 return 返回,然后在页面触发 componentWillMount 后即可通过 this.$preloadData 获取到预加载的内容。

class Index extends Component {
  componentWillMount () {
    console.log('isFetching: ', this.isFetching)
    this.$preloadData
      .then(res => {
        console.log('res: ', res)
        this.isFetching = false
      })
  }

  componentWillPreload (params) {
    return this.fetchData(params.url)
  }

  fetchData () {
    this.isFetching = true
    ...
  }
}

参考<<Taro 多端开发实现原理与项目实战>>