---
name: "useProps"
mode: "api"
versionRequirements:
  - { name: "@ray-js/panel-sdk", version: "1.2.0" }
title: "useProps - 基于 sdm 实例的 model.props 实现，能够在智能设备功能点变动时驱动组件重新渲染"
summary: "useProps 是 @ray-js/panel-sdk 提供的 React Hook，基于 sdm 实例的 model.props 实现，通过 selector 函数订阅指定功能点（如 props.power）的实时状态，功能点变动时自动驱动重渲染。内置 shallow equal 并支持自定义 equalityFn。不传 selector 会返回全部功能点状态但可能导致性能问题。支持单设备和群组。"
questions:
  - "怎么监听设备dp状态变化？怎么监听非raw类型的功能点状态变化？如何监听非结构化复杂类型的功能点状态变化？"
  - "useProps 如何通过 selector 函数订阅单个功能点（如 props.power）的实时状态变化？"
  - "useProps 内置 shallow equal 浅比较，如何通过自定义 equalityFn 仅在 power 变化时重渲染？"
  - "useProps() 不传参数或传 props => props 会返回所有功能点状态，为什么不推荐这种用法？"
  - "获取所有功能点状态会导致什么性能问题（频繁进行无效的重复渲染）？"
  - "useProps 的 TypeScript 泛型 ReadonlyDpSchemaList 和 GetSmartDeviceModelProps 分别代表什么？"
  - "useProps 的 selector 返回值类型 DpValue 可以是布尔、数值、字符串还是对象？"
  - "useProps 基于 sdm 实例的 model.props 实现，底层关联的 SDM API 是什么？"
  - "useProps 同时支持单设备和群组设备，两种环境下功能点状态的数据结构一致吗？"
  - "使用 useProps 前必须先挂载 SdmProvider，如何通过 public-sdm 模板项目快速接入？"
  - "useProps 与 useStructuredProps 的区别是什么（基础功能点 vs 配置协议的结构化复杂类型）？"
---

<div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>单设备支持</span>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>群组支持支持</span>
</div>

## useProps

> [VERSION] @ray-js/panel-sdk >= 1.2.0

> 💡 基于 sdm 实例实现。必须在 SdmProvider 内部使用。
> 使用前请注意检查项目是否已挂载了 SdmProvider，项目接入可参考 [智能设备模型 - 使用](/cn/miniapp/solution-panel/ability/common/sdm/usage)，全新项目可直接基于 [public-sdm](https://github.com/Tuya-Community/tuya-ray-materials/tree/main/template/PublicSdmTemplate) 示例项目进行开发。

### 描述

获取智能设备功能点状态，功能点变动时驱动组件重新渲染

### 参数

`Params`

| 参数 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| `selector` | `(props: DpState) => DpValue;` | 否 | 选择器函数，入参为当前设备环境下的全量功能点状态。   具体属性由 devices/schema.ts 中的 as const Schema 定义推导，   类型映射规则：bool → boolean, value/bitmap → number, enum/string/raw → string，详见示例代码 |
| `equalityFn` | `(prevDpValue: DpValue, nextDpValue: DpValue) => boolean` | 否 | 自定义比较函数，返回 true 则不触发重渲染 |

### 返回值

类型: `DpValue`

通过 selector 选择器选择后返回的功能点值，类型基于业务项目提供的 Schema 定义，按 property.type 自动推导值类型

**`type` DpValue**

```typescript
export type DpValue = boolean | number | string;
```

### 引用对象

##### `type` DpState

功能点状态对象，key 为功能点 code，value 为功能点值

```typescript
export type DpState = Record<string, DpValue>;
```

##### `type` DpValue

功能点值类型，可能为 boolean、number、string

```typescript
export type DpValue = boolean | number | string;
```


### 示例代码

#### 基础用法

```tsx
// 1. devices/schema.ts — as const 是类型推导的基石，基于业务项目提供的 Schema 定义，按 property.type 自动推导值类型
export const schema = [
  { code: 'switch_led', property: { type: 'bool' }, type: 'obj', mode: 'rw', id: 1, name: 'Switch' },
  { code: 'work_mode', property: { type: 'enum', range: ['white', 'colour'] }, type: 'obj', mode: 'rw', id: 2, name: 'Mode' },
  { code: 'brightness', property: { type: 'value', min: 10, max: 1000, step: 1 }, type: 'obj', mode: 'rw', id: 3, name: 'Brightness' },
  { code: 'fault', property: { type: 'bitmap', maxlen: 8 }, type: 'obj', mode: 'ro', id: 4, name: 'Fault' },
  { code: 'colour_data', property: { type: 'string', maxlen: 14 }, type: 'obj', mode: 'rw', id: 5, name: 'Colour' },
] as const;

// 2. useProps — 按 property.type 自动推导值类型
import { useProps } from '@ray-js/panel-sdk';

const power = useProps(dpState => dpState.switch_led);       // → boolean
const mode = useProps(dpState => dpState.work_mode);         // → string
const bright = useProps(dpState => dpState.brightness);      // → number
const fault = useProps(dpState => dpState.fault);            // → number
const colour = useProps(dpState => dpState.colour_data);     // → string
```

#### 自定义 rerender

```tsx
// 不传 selector 返回全量状态，则任意功能点变化都触发重渲染
const dpState = useProps(
  dpState => dpState,
  (prevDpValue, nextDpValue) => prevDpValue.switch_led === nextDpValue.switch_led, // 只会在返回 false 时 rerender
);
```

#### 获取所有功能点状态

```tsx
// 除非当前页面或组件需要监听所有功能点的变化，否则请勿使用该方式，会导致当前页面或组件出现性能问题，频繁进行无效的重复渲染。
import { useProps } from '@ray-js/panel-sdk';

const dpState1 = useProps();
const dpState2 = useProps(props => props);
```
