uni-app中jsx组件重复渲染问题,前两次渲染props正常,最后一次输出为default,h5端正常输出props

uni-app中jsx组件重复渲染问题,前两次渲染props正常,最后一次输出为default,h5端正常输出props

示例代码:

export default {
props: {
type: {
type: String,
default: 'default'
},
},
render(createElement) {
const { type } = this
console.log('type:', type)
// 警告按钮输出
if (type === 'warn') return createElement(
'view', // 标签名称
{
class: {
'bt-button': true,
'bt-button-warn': true
}
},
this.$slots.default // 子节点数组
)
// 默认输出按钮
return createElement(
'view', // 标签名称
{
class: {
'bt-button': true
}
},
this.$slots.default // 子节点数组
)
}
}

操作步骤:

在页面上引入js,然后声明组件就可以看到

预期结果:

type:, warn
type:, warn
type:, warn

实际结果:

type:, warn
type:, warn
type:, 

bug描述:

在写jsx组件中,组件重复渲染,前两次渲染props正常,但是最后一次输出为default,在h5正常输出props. 看了论坛上都是小程序的,没有报app的,想问下官方大佬怎么回事

注意:无论是window还是mac都是一样的结果

Image

信息类别 内容
产品分类 uniapp/App
PC开发环境 Mac
PC系统版本 macOS Mojave 10.14.6
开发工具 HBuilderX
工具版本 3.2.3
手机系统 Android
手机系统版本 Android 6.0
手机厂商 模拟器
手机机型 mumu模拟器
页面类型 vue
打包方式 云端
项目创建方式 HBuilderX

更多关于uni-app中jsx组件重复渲染问题,前两次渲染props正常,最后一次输出为default,h5端正常输出props的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

补充下,试过华为nova 7 5g版(鸿蒙系统),红米redmi5 android8.0.1是一样的结果,都渲染了三次,最后一次的结果是props默认值default

更多关于uni-app中jsx组件重复渲染问题,前两次渲染props正常,最后一次输出为default,h5端正常输出props的实战教程也可以访问 https://www.itying.com/category-93-b0.html


建议用symbol来判断下是否为空再执行

问题是这个type是传了也为空,就不太科学了,用.vue文件是行的,我用的是js文件写的jsx

这是一个已知的 uni-app App 端渲染机制问题。在 App 平台,自定义组件的 render 函数在某些情况下会被额外调用一次,此时 props 可能尚未完全初始化,导致读取到默认值。

问题原因: App 端的渲染流程与 H5 存在差异。组件的首次渲染可能分阶段进行,最后一次调用 render 时 props 可能处于中间状态,因此获取到的是默认值而非实际传入的值。

解决方案

  1. 添加空值判断:在 render 函数中增加对 props 的防御性判断。

    render(createElement) {
      const { type } = this
      // 增加判断,如果 type 为默认值且未传入有效值,可暂不渲染或使用默认视图
      if (!type || type === 'default') {
        // 返回一个空的 view 或默认结构
        return createElement('view')
      }
      // 原有逻辑...
    }
    
  2. 使用计算属性:通过计算属性确保数据稳定后再渲染。

    export default {
      props: { type: { type: String, default: 'default' } },
      computed: {
        currentType() {
          return this.type || 'default'
        }
      },
      render(createElement) {
        console.log('type:', this.currentType)
        // 使用 this.currentType 进行条件渲染
      }
    }
    
  3. 利用 v-if 控制渲染时机:在父组件中通过条件渲染避免初始空值问题。

    <template>
      <my-component v-if="type" :type="type" />
    </template>
回到顶部