---
name: "useProps"
mode: "api"
versionRequirements:
  - { name: "@ray-js/panel-sdk", version: "1.2.0" }
title: "useProps - Implemented based on model.props of the sdm instance, triggers component re-renders when smart device DP values change"
summary: "useProps is a React Hook provided by @ray-js/panel-sdk, implemented based on model.props of the sdm instance. Use a selector function to subscribe to the real-time state of a specific DP (e.g. props.power), and the component automatically re-renders when the DP changes. Built-in shallow equal with support for a custom equalityFn. Not passing a selector returns all DP states but may cause performance issues. Supports both single devices and groups."
questions:
  - "How to listen for device DP state changes? How to listen for non-raw type DP state changes? How to listen for non-structured complex type DP state changes?"
  - "How does useProps subscribe to real-time state changes of a single DP (e.g. props.power) via a selector function?"
  - "useProps has built-in shallow equal comparison. How to re-render only when power changes by using a custom equalityFn?"
  - "Calling useProps() without arguments or passing props => props returns all DP states. Why is this usage not recommended?"
  - "What performance issues can arise from getting all DP states (frequent unnecessary re-renders)?"
  - "What do the TypeScript generics ReadonlyDpSchemaList and GetSmartDeviceModelProps of useProps represent?"
  - "Can the selector return type DpValue of useProps be boolean, number, string, or object?"
  - "useProps is implemented based on model.props of the sdm instance. What underlying SDM API is associated?"
  - "useProps supports both single devices and groups. Is the DP state data structure consistent in both environments?"
  - "SdmProvider must be mounted before using useProps. How to quickly integrate via the public-sdm template project?"
  - "What is the difference between useProps and useStructuredProps (basic DPs vs structured complex types configured with protocols)?"
---

<div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>Device Support</span>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>Group Support</span>
</div>

## useProps

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

> 💡 Implemented based on the sdm instance. Must be used inside SdmProvider.
> Before using, ensure the project has mounted SdmProvider; see [Smart Device Model - Usage](/cn/miniapp/solution-panel/ability/common/sdm/usage). New projects can start from the [public-sdm](https://github.com/Tuya-Community/tuya-ray-materials/tree/main/template/PublicSdmTemplate) example.

### Description

Get smart device DP states; re-renders the component when DPs change

### Parameters

`Params`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `selector` | `(props: DpState) => DpValue;` | No | Selector function. The input is the full DP state in the current device context. Specific properties are inferred from the as const Schema defined in devices/schema.ts. Type mapping: bool → boolean, value/bitmap → number, enum/string/raw → string. See sample code |
| `equalityFn` | `(prevDpValue: DpValue, nextDpValue: DpValue) => boolean` | No | Custom comparator; returning true prevents re-render |

### Return Value

Type: `DpValue`

DP value returned by the selector; its type is based on the project-provided Schema and is inferred from property.type

**`type` DpValue**

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

### Referenced Types

##### `type` DpState

Datapoint status object, where the key is the datapoint code and the value is the datapoint value.

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

##### `type` DpValue

Datapoint value type, which can be boolean, number, or string.

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


### Examples

#### Basic usage

```tsx
// 1. devices/schema.ts — 'as const' is the cornerstone of type inference; based on the project's Schema, value types are inferred automatically by 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 — Automatically infer value types by 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
```

#### Custom rerender

```tsx
// Without a selector, the full state is returned, so any DP change triggers a rerender
const dpState = useProps(
  dpState => dpState,
  (prevDpValue, nextDpValue) => prevDpValue.switch_led === nextDpValue.switch_led, // Rerenders only when this returns false
);
```

#### Get all DP states

```tsx
// Unless the current page or component needs to listen to changes of all DPs, do not use this approach; it may cause performance issues and frequent redundant re-renders.
import { useProps } from '@ray-js/panel-sdk';

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