PanelOutdoorCycle和AiEarphoneTemplate渲染失败
渲染这两个模板的时候失败,让AI分析的时候给出的结论:
一、PanelOutdoorCycle:schema.ts 只声明了 1 个 DP,与代码实际使用的 DP 无交集
模板:PanelOutdoorCycle(public-sdm-template@1.0.2)
下载地址:https://static1.tuyacn.com/static/txp-raytpl-PanelOutdoorCycle/template.tar
症状
面板能渲染——地图、电量、"更多"入口都正常显示——但功能控件区整片空白,
一个控件都不出现。
原因
src/devices/schema.ts 全文只声明了一个 DP:
Code: Select all
export const defaultSchema = [
{
id: 1,
code: 'switch_1',
name: '开关1',
type: 'obj',
property: { type: 'bool' },
mode: 'rw',
// ...
},
] as const;而同一模板的 src/constant/dpCodes.ts 列举了 40 个 DP code:
Code: Select all
mileageTotal: 'mileage_total', // 总里程
enduranceMileage: 'endurance_mileage', // 续航里程
blelockSwitch: 'blelock_switch', // 防盗开关
batteryPercentage: 'battery_percentage', // 电池电量
headlightSwitch: 'headlight_switch', // 大灯开关
level: 'level', // 档位切换
mode: 'mode', // 模式切换
// ... 共 40 条代码里有 24 处 supportDp(dpCodes.xxx) 调用,按这些 code 判断该不该渲染对应控件,
覆盖 mileageTotal / blelockSwitch / headlightSwitch / level / mode /
autoLightSwitch / moveAlarm / bucketLock 等。
两边没有任何交集 —— switch_1 不在那 40 个 code 里,那 40 个也全都不在 schema 里。
因此每一个 supportDp() 都返回 false,控件区必然为空。
期望
补全 src/devices/schema.ts,把代码实际用到的那些 DP(至少是 24 处 supportDp()
覆盖到的约 18 个 code)按完整结构声明进去,含 id / code / type / mode /
property。
二、AiEarphoneTemplate:在 App 作用域调用了页面级 hook,导致整个面板白屏
模板:AiEarphoneTemplate(ai-earphone-template@1.0.0)
下载地址:https://static1.tuyacn.com/static/txp-raytpl-AiEarphoneTemplate/template.tar
相关依赖:@ray-js/panel-sdk@1.16.1 → 内嵌 @ray-core/framework-shared@0.3.9
症状
整页白屏,React 树完全没有挂载。控制台首个错误:
Code: Select all
TypeError: Cannot read properties of null (reading 'addLifecycle')
at onLaunch → _render → updateContainer原因
src/app.tsx:44,在 App 组件里调用了 usePanelConfig():
Code: Select all
const App = ({ children }) => {
const [initialized, setInitialized] = useState(false);
const [offlineUsage, setOfflineUsage] = useState(false);
const panelConfig = hooks.usePanelConfig(); // ← 这里而 usePanelConfig() 内部第一件事就是注册页面生命周期:
Code: Select all
// @ray-js/panel-sdk/lib/hooks/usePanelConfig/index.js
export function usePanelConfig() {
const [panelConfig, setPanelConfig] = useState(__panelConfig);
// ...
usePageEvent('onReady', () => { ... });usePageEvent 来自 @ray-core/framework-shared@0.3.9:
Code: Select all
// esm/hooks.js
export function usePageEvent(eventName, callback) {
var pageInstance = useContext(PageInstanceContext);
useLayoutEffect(function () {
if ('function' === typeof pageInstance.addLifecycle) { // ← pageInstance 为 null
// esm/PageInstanceContext.js
var PageInstanceContext = React.createContext(null); // ← 默认值就是 nullPageInstanceContext 的 Provider 只由页面包装器提供。App 在 onLaunch 阶段执行,
那时一个页面实例都还不存在,useContext 拿到默认值 null,
typeof null.addLifecycle 直接抛 TypeError。异常发生在 updateContainer 期间,
整棵 React 树没能挂载,所以是白屏而不是局部报错。
期望
把 usePanelConfig() 从 App 里移到页面组件中调用(或改用不依赖页面实例的方式
获取 panelConfig)。这是页面级 hook 的使用位置问题,与运行环境无关。
说明
这条调用链完全不经过 ty.*,所以任何小程序运行时 mock 都触及不到,
在真机上是否表现相同取决于时序,但从代码看 App 阶段必然拿不到页面实例。