This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
useNativeState
一个 React Hook,用于创建在 JavaScript 和原生 SwiftUI 视图之间共享的可观察状态。
useNativeState 返回一个 ObservableState,它在原生侧映射到 SwiftUI 的 ObservableObject,因此对 .value 的读取和写入会直接被 SwiftUI 观察到,而不会经过 React 渲染周期。这使你可以从 UI 线程上的 worklet 同步更新原生视图。
注意: 当使用 React Compiler 时,你应避免直接访问和修改
value属性。相反,请使用get和set方法,它们符合 React Compiler 标准。
安装
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
用法
注意: 使用 worklet 需要在你的项目中安装
react-native-worklets。useNativeState本身无需它即可工作,但下面展示的同步 UI 线程更新依赖于 worklet 运行时。
下面的示例会在用户输入时对电话号码进行掩码处理。格式化以及对 maskedPhone.value(文本)和 selection.value(光标位置)的写入都在 UI 线程上同步发生,因此输入值和掩码后的值之间不会出现闪烁。
import { Host, TextField, useNativeState } from '@expo/ui/swift-ui'; import { keyboardType } from '@expo/ui/swift-ui/modifiers'; import { useEffectEvent } from 'react'; export default function WorkletPhoneMaskExample() { const maskedPhone = useNativeState(''); const selection = useNativeState({ start: 0, end: 0 }); const handleTextChange = useEffectEvent((v: string) => { 'worklet'; const digits = v.replace(/\D/g, '').slice(0, 10); let formatted: string; if (digits.length === 0) { formatted = ''; } else if (digits.length <= 3) { formatted = digits; } else if (digits.length <= 6) { formatted = `(${digits.slice(0, 3)}) ${digits.slice(3)}`; } else { formatted = `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`; } if (formatted !== v) { maskedPhone.value = formatted; // 演示中会跳转到末尾。实际的掩码需要更智能的光标处理。 selection.value = { start: formatted.length, end: formatted.length }; } }); return ( <Host matchContents> <TextField text={maskedPhone} selection={selection} placeholder="(555) 123-4567" modifiers={[keyboardType('phone-pad')]} onTextChange={handleTextChange} /> </Host> ); }
API
import { useNativeState } from '@expo/ui/swift-ui';
Hooks
| Parameter | Type |
|---|---|
| initialValue | T |
Creates an observable native state that is automatically cleaned up when the
component unmounts. initialValue is captured once on the first render
ObservableState<T>Types
Observable state shared between JavaScript and native views (Jetpack Compose on Android and SwiftUI on iOS).
Type: SharedObject extended by:
| Property | Type | Description |
|---|---|---|
| onChange | [listener] | null | A single listener invoked on the native UI runtime whenever the value changes
(after iOS The callback must be a worklet so it can run synchronously on the UI thread.
Attach it inside Example
|
| value | T | The current value. Writes from a UI worklet are synchronous and immediately readable. Writes from the JS thread are scheduled to the UI thread asynchronously, the new value is not readable until the update has been applied. Prefer writing from a worklet when you need synchronous updates |
| get | () => T | Reads the current value. A React Compiler compliant alternative to reading |
| set | (value: T) => void | Writes a new value. A React Compiler-compliant alternative to assigning |