单设备支持群组支持

useStructuredProps(selector?: (structuredProps: object) => any, equalityFn?: (prev: any, next: any) => boolean)

版本要求:
@ray-js/panel-sdk≥1.10.0

描述

获取经 dp-kit 协议解析后的结构化功能点状态,状态变更时驱动组件重新渲染

参数

参数类型必填说明
selector(structuredProps: object) => any否选择器函数,入参为结构化状态对象(每个 key 的值类型由 protocols 中对应 Transformer.parser() 的返回值决定),返回需要订阅的部分;不传则返回全部结构化功能点状态,注意不会返回基础数据类型功能点。
equalityFn(prev: any, next: any) => boolean否自定义比较函数,入参为 selector 前后两次的返回值,返回 true 则不触发重渲染,默认 shallow equal

返回值

类型:any
selector 的返回值,其类型由 selector 决定;未传 selector 时返回完整的结构化状态对象(每个 key 的值类型 = 对应 Transformer.parser() 的返回值类型)

示例代码

完整接入链路(以照明 colour_data 为例)

// ---- 1. Parser:SDK 内置 ColourTransformer 源码参考 ----
// Transformer 接口:{ uuid, defaultValue, parser(dpStr) → T, formatter(data: T) → string }
// parser 的返回值类型 T 决定了 useStructuredProps 中对应 DP code 的结构化类型
// 自定义 parser 同理,实现 parser + formatter 即可
type TColorData = { hue: number; saturation: number; value: number };

class ColourTransformer implements Transformer<TColorData> {
  defaultValue = { hue: 10, saturation: 1000, value: 1000 };
  uuid = 'colour_data';

  // parser 返回 TColorData → useStructuredProps 中 props.colour_data 即为此类型
  parser(value: string): TColorData {
    if (value.length !== 12) return this.defaultValue;
    const step = generateDpStrStep(value);
    return { hue: step(4).value, saturation: step(4).value, value: step(4).value };
  }

  formatter(data: TColorData) {
    const { hue, saturation, value } = data;
    return `${decimalToHex(hue, 4)}${decimalToHex(saturation, 4)}${decimalToHex(value, 4)}`;
  }
}

// ---- 2. devices/protocols/index.ts:实例化 parser 并映射到 DP code ----
import { protocols as sdkProtocols } from '@ray-js/panel-sdk';
import { lampSchemaMap } from '../schema';

export const protocols = {
  // 实际变量名称为 colour_data,映射到 DP code
  [lampSchemaMap.colour_data.code]: new sdkProtocols.ColourTransformer(),
};

// ---- 3. devices/index.ts:创建 dpKit 并传给 sdm 实例 ----
import { SmartDeviceModel, createDpKit } from '@ray-js/panel-sdk';
import { protocols } from '@/devices/protocols';

export const dpKit = createDpKit({ protocols });
export const devices = {
  lamp: new SmartDeviceModel({ interceptors: dpKit.interceptors }),
};

// ---- 4. 页面组件:通过 useStructuredProps 消费结构化数据 ----
// props.colour_data 的类型 = ColourTransformer.parser() 的返回值 TColorData
// 即 { hue: number; saturation: number; value: number }
import { useStructuredProps } from '@ray-js/panel-sdk';
export default function Home() {
  const colour = useStructuredProps(props => props.colour_data);
  return (
    <View>
      <View>hue: {colour.hue}</View>
      <View>saturation: {colour.saturation}</View>
      <View>value: {colour.value}</View>
    </View>
  );
}

自定义 rerender

import React from 'react';
import { View } from '@ray-js/ray';
import { useStructuredProps } from '@ray-js/panel-sdk';

export default function Home() {
  const dpState = useStructuredProps(
    d => d,
    (prevDpState, nextDpState) => prevDpState.colour_data?.hue === nextDpState.colour_data?.hue, // 只会在返回 false 时 rerender
  );
  return (
    <View>
      <View>hue: {dpState.colour_data?.hue}</View>
      <View>saturation: {dpState.colour_data?.saturation}</View>
      <View>value: {dpState.colour_data?.value}</View>
    </View>
  );
}