Skip to content

在 Taro 中使用原生组件遇到的坑

callMethod error undefined is not object

这个坑是我使用 Taro 编写支付宝小程序并使用【码上有钱】保险勾选框组件(弹窗形态)时遇到的。

首先,我是按照 Taro 文档中使用原生模块的方法和【码上有钱】勾选框组件接入流程进行保险勾选框组件(弹窗形态)的接入。

ts
export default defineAppConfig({
  plugins: {
    xlightPlugin: {
      version: '*',
      provider: '2021xxxxxxxxx',
    },
  },
})
ts
export default definePageConfig({
  usingComponents: {
    'riding-risk-component-pop':
      'plugin://xlightPlugin/riding-risk-component-pop',
  },
})
tsx
export default function Page() {
  const [visible, setVisible] = useState(false)
  const ridingRiskRtaExtMap = {}
  const ridingRiskSpaceCode = '该code为申请的spaceCode'

  const onPopRiding = () => {
    setVisible(true)
  }

  const onPopupClose = () => {
    setVisible(false)
  }

  const onInsuranceStatus = () => {
    console.log('用户完成了投保动作')
  }

  const onSuccess = () => {
    console.log('广告加载成功')
  }

  const onClose = () => {
    console.log('广告关闭')
  }

  const onError = () => {
    console.log('广告加载失败')
  }

  return (
    <Button onClick={onPopRiding}>保险弹窗</Button>
    <riding-risk-component-pop
      visible={visible}
      onPopupClose={onPopupClose}
      onInsuranceStatus={onInsuranceStatus}
      spaceCode={ridingRiskSpaceCode}
      rtaExtMap={ridingRiskRtaExtMap}
      onSuccess={onSuccess}
      onClose={onClose}
      onError={onError}
    />
  )
}

当我把打包后的产物放在开发者工具运行时就会报 callMethod error undefined is not object 这个错误。

原因请查看该 comment

解决方法:创建一个自定义组件包裹该原生组件。

假设项目源码都放置在 src 目录下。

src/components 目录下创建 MyRidingRiskComponentPop 目录,内容如下:

html
<riding-risk-component-pop
  visible="{{visible}}"
  onPopupClose="onPopupClose"
  onInsuranceStatus="onInsuranceStatus"
  spaceCode="{{spaceCode}}"
  rtaExtMap="{{rtaExtMap}}"
  onSuccess="onSuccess"
  onClose="onClose"
  onError="onError"
/>
json
{
  "component": true,
  "usingComponents": {
    "riding-risk-component-pop": "plugin://xlightPlugin/riding-risk-component-pop"
  }
}
js
Component({
  props: {
    id: '',
    visible: false,
    spaceCode: '',
    rtaExtMap: {},
    onPopupClose: () => {},
    onInsuranceStatus: () => {},
    onSuccess: () => {},
    onClose: () => {},
    onError: () => {},
  },
  methods: {
    onPopupClose(obj) {
      this.props.onPopupClose({
        type: 'popup-close',
        currentTarget: {
          id: this.props.id,
          dataset: obj,
        },
      })
    },
    onInsuranceStatus(obj) {
      this.props.onInsuranceStatus({
        type: 'insurance-status',
        currentTarget: {
          id: this.props.id,
          dataset: { ...obj },
        },
      })
    },
    onSuccess(obj) {
      this.props.onSuccess({
        type: 'success',
        currentTarget: {
          id: this.props.id,
          dataset: { ...obj },
        },
      })
    },
    onClose(obj) {
      this.props.onClose({
        type: 'close',
        currentTarget: {
          id: this.props.id,
          dataset: { ...obj },
        },
      })
    },
    onError(obj) {
      this.props.onError({
        type: 'error',
        currentTarget: {
          id: this.props.id,
          dataset: { ...obj },
        },
      })
    },
  },
})

然后在页面里引用这个组件。

ts
export default definePageConfig({
  usingComponents: {
    'my-riding-risk-component-pop':
      '../../components/MyRidingRiskComponentPop/index',
  },
})
tsx
export default function Page() {
  const [visible, setVisible] = useState(false)
  const ridingRiskRtaExtMap = {}
  const ridingRiskSpaceCode = '该code为申请的spaceCode'

  const onPopRiding = () => {
    setVisible(true)
  }

  const onPopupClose = () => {
    setVisible(false)
  }

  const onInsuranceStatus = () => {
    console.log('用户完成了投保动作')
  }

  const onSuccess = () => {
    console.log('广告加载成功')
  }

  const onClose = () => {
    console.log('广告关闭')
  }

  const onError = () => {
    console.log('广告加载失败')
  }

  return (
    <Button onClick={onPopRiding}>保险弹窗</Button>
    <my-riding-risk-component-pop
      id="my-riding-risk-component-pop"
      visible={visible}
      onPopupClose={onPopupClose}
      onInsuranceStatus={onInsuranceStatus}
      spaceCode={ridingRiskSpaceCode}
      rtaExtMap={ridingRiskRtaExtMap}
      onSuccess={onSuccess}
      onClose={onClose}
      onError={onError}
    />
  )
}

WARNING

id 一定要传,否则回调函数不会执行。

References