混合编写 RN
在编写 Mpx 组件时,在某些出于性能考虑的特定情况下,可能会涉及到 Mpx 和 RN 混合编写:在 Mpx 项目内直接使用 RN 组件和编写 RN 代码。
混合使用 RN 组件
RN 组件注册
在 Mpx 组件内引用 RN 组件,需在 components 选项中进行注册。
选项式 API
html
<template>
<view>
<!-- RN View 组件 -->
<View>
<!-- RN Text 组件 -->
<Text> 我是 RN 组件 </Text>
<!-- Mpx 组件 -->
<view> 我是 Mpx 组件 </view>
<!-- 支持在 RN 组件内部定义插槽 -->
<slot name="myslot"></slot>
</View>
</view>
</template>
<script>
import { createComponent } from "@mpxjs/core"
import { View, Text } from "react-native"
createComponent({
components: {
View,
Text,
},
})
</script>组合式 API
组合式 API 需要在 defineOptions 中进行类似选项式 API 的 components 组件注册。
html
<script setup>
import { View, Text } from "react-native"
defineOptions({
components: {
View,
Text,
},
})
defineExpose({})
</script>RN 组件样式属性 style
RN 组件支持样式属性的透传,style/wx:style 样式属性用法与小程序一致,并且额外支持 RN 数组样式定义方式。
html
<template>
<view>
<!-- style -->
<Text style="color: red"> 字符串形式 value </Text>
<Text style="{{ {color: 'red'} }}"> 对象形式样式 value </Text>
<Text style="{{ [{color: 'red'}] }}"> 数组形式样式 value </Text>
<!-- wx:style -->
<Text wx:style="color: red"> 字符串形式 value </Text>
<Text wx:style="{{ {color: 'red'} }}"> 对象形式样式 value </Text>
<Text wx:style="{{ [{color: 'red'}] }}"> 数组形式样式 value </Text>
</view>
</template>RN 组件的属性与事件
- RN 组件属性与事件参考 RN 原生支持的属性与事件名,对应赋值方式按照 Mpx 语法进行双括号包裹。
- 组件使用的值既可以沿用 Mpx 组件的
data、computed等响应式数据,也可以通过 使用 React Hooks 返回值进行声明。
注意
使用 React Hooks 导出的变量如果需要在模板上进行响应式更新,需要配合组件设置 disableMemo: true 使用,详见下方配合模板响应式。
使用 React Hooks
选项式 API
Mpx 提供了 React Hooks 执行机制,通过在 Mpx 组件内注册 REACTHOOKSEXEC 方法,保障 RN 组件的初始化执行。Hooks 的返回值支持数据与方法,比如:
- 模板上 RN 组件与 Mpx 组件的数据渲染
- 模板上的 props 传递
- 模板上的样式定义
- 模板上的事件的绑定与透传
html
<template>
<view>
<View onTouchEnd="{{ onTouchEnd }}">
<Text> Count: {{ count }} </Text>
</View>
</view>
</template>
<script>
import { createComponent, REACTHOOKSEXEC } from "@mpxjs/core"
import { View, Text } from "react-native"
import { useState } from "react"
createComponent({
components: {
View,
Text,
},
[REACTHOOKSEXEC]() {
// 所有使用 hooks 的部分在此处进行注册与执行
const [count, setCount] = useState(0)
const onTouchEnd = () => {
console.log("trigger event: onTouchEnd")
setCount((count) => count + 1)
}
// 返回值可直接用于模板
return {
count,
onTouchEnd,
}
},
})
</script>组合式 API
Mpx 也支持组合式 API 的使用,使用方式与选项式 API 类似,均在 onReactHooksExec 方法内进行 hooks 的注册与执行
html
<script setup>
import { onReactHooksExec } from "@mpxjs/core"
import { View, Text } from "react-native"
import { useState } from "react"
defineOptions({
components: {
View,
Text,
},
})
onReactHooksExec(() => {
const [count, setCount] = useState(0)
const onTouchEnd = () => {
console.log("trigger event: onTouchEnd")
setCount((count) => count + 1)
}
return {
count,
onTouchEnd,
}
})
defineExpose({})
</script>配合模板响应式
如果你尝试了上面的示例代码,可能会好奇为什么点击后控制台正常打印了日志 trigger event: onTouchEnd,但是模板上的 count 并没有更新呢?
这是因为出于性能优化的考虑,Mpx 默认不会对 React Hooks 返回值进行响应式更新。 如果需要对使用 React Hooks 返回的变量在模板上进行响应式更新,可以通过在组件的 options 选项中配置 disableMemo: true 来开启,开启后也会关闭 RN 组件的性能优化。
选项式 API:
js
createComponent({
// ...
options: {
disableMemo: true,
},
})组合式 API:
js
defineOptions({
// ...
options: {
disableMemo: true,
},
})