import { DpValue } from '../../types'; import { DpKitProtocols, GetStructuredDpState } from '../types/dp-kit'; /** * 获取经 dp-kit 协议解析后的结构化功能点状态,状态变更时驱动组件重新渲染 * @public * @since @ray-js/panel-sdk 1.10.0 * @param selector - 选择器函数,入参为结构化状态对象(每个 key 的值类型由 protocols 中对应 Transformer.parser() 的返回值决定),返回需要订阅的部分;不传则返回全部结构化功能点状态,注意不会返回基础数据类型功能点。 * @typeOverride selector (structuredProps: object) => any * @param equalityFn - 自定义比较函数,入参为 selector 前后两次的返回值,返回 true 则不触发重渲染,默认 shallow equal * @typeOverride equalityFn (prev: any, next: any) => boolean * @returns selector 的返回值,其类型由 selector 决定;未传 selector 时返回完整的结构化状态对象(每个 key 的值类型 = 对应 Transformer.parser() 的返回值类型) * @typeOverride returns any * @remarks * 基于 sdm 实例及 dp-kit 拦截器实现。必须在 SdmProvider 内部使用。 * 使用前请注意检查项目是否已挂载了 SdmProvider,项目接入可参考 [智能设备模型 - 使用](/cn/miniapp/solution-panel/ability/common/sdm/usage),全新项目可直接基于 [public-sdm](https://github.com/Tuya-Community/tuya-ray-materials/tree/main/template/PublicSdmTemplate) 示例项目进行开发。 * 使用前请注意检查是否已配置接入了 dp-kit 拦截器,项目接入可参考 [拦截器 - 使用](/cn/miniapp/solution-panel/ability/common/sdm/interceptors/usage)。 * 出于 hooks 功能单一性和稳定性考虑,useStructuredProps 只会返回配置了协议规则的功能点,不会返回基础数据类型功能点。 * 典型场景:colour_data 等复合字符串字段,dp-kit 根据 protocols 协议自动解析为 * `{ hue, saturation, value }` 等结构化对象。 * * @example 完整接入链路(以照明 colour_data 为例) * ```ts * // ---- 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 { * 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 ( * * hue: {colour.hue} * saturation: {colour.saturation} * value: {colour.value} * * ); * } * ``` * @example 自定义 rerender * ```tsx * 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 ( * * hue: {dpState.colour_data?.hue} * saturation: {dpState.colour_data?.saturation} * value: {dpState.colour_data?.value} * * ); * } * ``` */ export declare function useStructuredProps(selector?: (props: GetStructuredDpState) => V, equalityFn?: (a: V, b: V) => boolean): V;