如果你也遇到这个问题,大概率说明你没有认真读过taro的文档,是不是有点气,
我敢这么说是因为我就是,遇到了这个坑才想起来认真去看看文档。
不过踩坑这个过程也是必要的,单纯地枯燥的看文档并不是最好的方法,
遇到问题再去认真看下文档理解下,也未尝不可。
废话太多!!!进入正题。
问题:
目录结构
- src
- components
- good-item
- pages
- good-list
- components
good-item组件
注意下面renderTitle的传值方式
class GoodItem extends Component {
constructor(props){
super(props)
}
render () {
const {renderTitle} = this.props
return (<View>
{this.props.renderTitle}
</View>)
}
}
good-list页面
import {GoodItem} from '../../components';
class Goods extends Component {
constructor(props){
super(props)
this.state = {
title:'我是标题'
}
}
render () {
return (
<View className='index'>
商品
<GoodItem
renderTitle={<View>{this.state.title}</View>}
>
</GoodItem>
</View>
)
}
}
写pc端react的时候这样肯定是没有问题,但是写taro的时候却渲染不出来我们想要的<View>{this.state.title}</View>
解决
取消props解构的形式传入,正确的是good-item组件中使用{this.props.renderTitle}
原因
文档中已经明确的说过:传送门->嗖~
请不要对 this.props.children 进行任何操作。Taro 在小程序中实现这个功能使用的是小程序的 slot 功能,也就是说你可以把 this.props.children 理解为 slot 的语法糖,this.props.children 在 Taro 中并不是 React 的 ReactElement 对象,因此形如 this.props.children && this.props.children、this.props.children[0] 在 Taro 中都是非法的。
this.props.children 无法用 defaultProps 设置默认内容。由于小程序的限制,Taro 也无法知道组件的消费者是否传入内容,所以无法应用默认内容。
不能把 this.props.children 分解为变量再使用。由于普通的 props 有一个确切的值,所以当你把它们分解为变量运行时可以处理,this.props.children 则不能这样操作,你必须显性地把 this.props.children 全部都写完整才能实现它的功能。
如果不明白可以看下小程序slot的文档:传送门->嗖的一下~
this.props.renderTitle会编译为一下这种形式的插槽
good-list页面
<block>
<view class="index">商品
<good-item __triggerObserer="{{ _triggerObserer }}">
<view slot="title">{{title}}</view>
</good-item>
</view>
</block>
good-item组件
<block>
<view>
<slot name="title"></slot>
</view>
</block>
this.props.children就是没有命名的插槽的写法了
下面看下renderTitle 在props中解构与不解构的的对比
标黄色的文件名可以区分
可以看到:
- 不解构直接是编译为插槽的形式,开启多插槽的配置,并且state中不会存放renderTitle属性
- 而解构处理的,则是根本没有用到插槽,试图继续使用state存放jsx标签,但是要知道小程序的限制,不允许标签直接存放在state中。
所以,taro相对于react的,不支持的写法都是与小程序的限制是有关系的,如果遇到坑,可以先从原生小程序上去思考,或者索性直接打包一下 ,看看打包成什么了。
不过这些都要建立在认真读过文档的基础上哦~
完