Shopify Remix应用中Resource Picker报错‘this.app.subscribe is not a function’的解决方法求助
Shopify Remix应用中Resource Picker报错‘this.app.subscribe is not a function’的解决方法求助
嘿,我之前也踩过这个一模一样的坑!折腾了好一阵子才摸清楚几个有效的解决方向,给你梳理下:
先排查依赖版本兼容性
最常见的诱因就是@shopify/app-bridge和@shopify/app-bridge-react的版本不匹配,比如一个是v2一个是v3,API就会出现不兼容的情况。你可以打开package.json看看这两个包的版本,最好把它们统一升级到最新的稳定版,或者指定成对的兼容版本(比如都用3.x系列)。
修复ResourcePicker实例的引用问题
你代码里的resourcePicker变量没用到useRef保存,每次useEffect执行(比如app状态变化)都会重新创建实例,而且openPicker里拿到的可能是旧的或者undefined的引用,这也会引发奇怪的报错。改成用useRef存储实例就稳了:
import { ResourcePicker } from "@shopify/app-bridge/actions"; import { useAppBridge } from "@shopify/app-bridge-react"; import { useEffect, useRef } from "react"; // 用useRef保存picker实例,避免组件重渲染时丢失引用 const resourcePickerRef = useRef<ResourcePicker | null>(null); const app = useAppBridge(); useEffect(() => { if (!app) return; // 先清理之前的实例和订阅,防止内存泄漏 if (resourcePickerRef.current) { resourcePickerRef.current.unsubscribeAll(); resourcePickerRef.current.destroy(); } // 创建新的picker实例 const picker = ResourcePicker.create(app, { resourceType: ResourcePicker.ResourceType.Product, options: { selectMultiple: true, }, }); // 订阅选择事件 const unsubscribe = picker.subscribe( ResourcePicker.Action.SELECT, (selection) => { console.log("选中的内容: ", selection); } ); // 把实例存到ref里 resourcePickerRef.current = picker; // 组件卸载时清理资源 return () => { unsubscribe(); picker.destroy(); }; }, [app]); const openPicker = () => { // 用ref里的实例来触发打开 if (resourcePickerRef.current) { resourcePickerRef.current.dispatch(ResourcePicker.Action.OPEN); } };
确认App Bridge的初始化配置
在Remix应用里,一定要确保根组件(比如app/root.tsx)已经正确用AppProvider包裹,并且传入了shopOrigin等必要参数。如果App Bridge没有在正确的上下文初始化,useAppBridge返回的实例可能是不完整的,就会出现subscribe不是函数的报错。
额外的小提示
如果你用的是TypeScript,尽量别用any标注selection类型,可以导入Shopify提供的类型:
import { Selection } from '@shopify/app-bridge/actions/ResourcePicker'; // 然后把(selection: any)改成(selection: Selection)
备注:内容来源于stack exchange,提问作者noahacla
相关产品推荐
相关产品推荐

