Expo
Expo 和相关包的一组常用方法和类型。
安装
🌐 Installation
- npx expo install expo应用接口
🌐 API
import * as Expo from 'expo';
expo/fetch API
expo/fetch 提供了一个符合 WinterCG 的 Fetch API,可以在网页和移动环境中稳定运行,确保在 Expo 应用中实现标准化的跨平台 fetch 体验。
import { fetch } from 'expo/fetch'; const resp = await fetch('https://httpbin.org/drip?numbytes=512&duration=2', { headers: { Accept: 'text/event-stream' }, }); const reader = resp.body.getReader(); const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) { break; } chunks.push(value); } const buffer = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); console.log(buffer.length); // 512
API 编码
🌐 Encoding APIs
TextEncoder 和 TextDecoder 是内置的 API,用于以各种字符编码对文本进行编码和解码。它们在所有平台上都可用。有关 Web 和 Node.js 的支持情况,请参阅 浏览器和服务器运行时支持。
// [104, 101, 108, 108, 111] const hello = new TextEncoder().encode('hello'); // "hello" const text = new TextDecoder().decode(hello);
TextEncoder API 已包含在 Hermes 引擎中。请参阅 Hermes GitHub 仓库中 TextEncoder.cpp 的源代码。
🌐 The TextEncoder API is included in the Hermes engine. See the source code in TextEncoder.cpp inside the Hermes GitHub repository.
TextDecoder API 在原生平台上不符合规范。只支持 UTF-8 编码。如果你需要支持更多编码,可以使用像 text-encoding 这样的填充库。
🌐 The TextDecoder API is not spec-compliant on native platforms. Only the UTF-8 encoding is supported. If you need support for more encodings, use a polyfill like text-encoding.
这些 API 的流式等效版本 TextEncoderStream 和 TextDecoderStream 在所有平台上也可用。它们允许你以流的方式进行文本的编码和解码,这对于处理大量数据而不需要一次性将其全部加载到内存中非常有用。
🌐 The stream equivalents of these APIs, TextEncoderStream and TextDecoderStream, are also available on all platforms. They allow you to encode and decode text in a streaming manner, which is useful for processing large amounts of data without loading it all into memory at once.
const encoder = new TextEncoderStream(); const stream = new ReadableStream({ start(controller) { controller.enqueue('Hello'); controller.enqueue('World'); controller.close(); }, }); const reader = stream.pipeThrough(encoder).getReader(); reader.read().then(({ done, value }) => { console.log(value); // Uint8Array [72, 101, 108, 108, 111] });
Streams API
在本地平台上提供对标准网络流的全球支持,以匹配网页和服务器平台的行为。有关特定的网页和 Node.js 支持,请参阅 浏览器和服务器运行时支持。EAS Hosting 服务器运行时也包括对标准网络流 API 的支持。
🌐 Global support for standard web streams is available on native platforms to match the behavior of web and server platforms. Refer to the browser and server runtime support for specific web and Node.js support. EAS Hosting server runtime also includes support for the standard web streams API.
在全球范围内访问 ReadableStream、WritableStream 和 TransformStream 类。
🌐 Globally access ReadableStream, WritableStream, and TransformStream classes.
const stream = new ReadableStream({ start(controller) { controller.enqueue('Hello'); controller.enqueue('World'); controller.close(); }, }); const reader = stream.getReader(); reader.read().then(({ done, value }) => { console.log(value); // Hello }); reader.read().then(({ done, value }) => { console.log(value); // World });
URL接口
🌐 URL API
URL 在所有平台上提供标准 API。
在本地平台上,内置的 URL 和 URLSearchParams 实现替代了 react-native 中的填充。有关 Web 和 Node.js 的支持情况,请参阅 浏览器和服务器运行时支持。
🌐 On native platforms, built-in URL and URLSearchParams implementations replace the shims in react-native. Refer to the browser and server runtime support for web and Node.js.
const url = new URL('https://expo.dev'); const params = new URLSearchParams();
Expo 内置的 URL 支持尝试完全符合 规范。唯一缺失的例外是本地平台目前不支持主机名中的 非 ASCII 字符。
🌐 Expo's built-in URL support attempts to be fully spec compliant. The only missing exception is that native platforms do not currently support non-ASCII characters in the hostname.
console.log(new URL('http://🥓').toString()); // This outputs the following: // - Web, Node.js: http://xn--pr9h/ // - Android, iOS: http://🥓/
Constants
Hooks
| Parameter | Type | Description |
|---|---|---|
| eventEmitter | EventEmitter<TEventsMap> | An object that emits events. For example, a native module or shared object or an instance of |
| eventName | TEventName | Name of the event to listen to. |
| initialValue(optional) | null | TInitialValue | An event parameter to use until the event is called for the first time. Default: null |
React hook that listens to events emitted by the given object. The returned value is an event parameter that gets updated whenever a new event is dispatched.
InferEventParameter<TEventListener, TInitialValue>A parameter of the event listener.
Example
import { useEvent } from 'expo'; import { VideoPlayer } from 'expo-video'; export function PlayerStatus({ videoPlayer }: { videoPlayer: VideoPlayer }) { const { status } = useEvent(videoPlayer, 'statusChange', { status: videoPlayer.status }); return <Text>{`Player status: ${status}`}</Text>; }
| Parameter | Type | Description |
|---|---|---|
| eventEmitter | EventEmitter<TEventsMap> | An object that emits events. For example, a native module or shared object or an instance of |
| eventName | TEventName | Name of the event to listen to. |
| listener | TEventListener | A function to call when the event is dispatched. |
React hook that listens to events emitted by the given object and calls the listener function whenever a new event is dispatched. The event listener is automatically added during the first render and removed when the component unmounts.
voidExample
import { useEventListener } from 'expo'; import { useVideoPlayer, VideoView } from 'expo-video'; export function VideoPlayerView() { const player = useVideoPlayer(videoSource); useEventListener(player, 'playingChange', ({ isPlaying }) => { console.log('Player is playing:', isPlaying); }); return <VideoView player={player} />; }
Classes
A class that provides a consistent API for emitting and listening to events.
It shares many concepts with other emitter APIs, such as Node's EventEmitter and fbemitter.
When the event is emitted, all of the functions attached to that specific event are called synchronously.
Any values returned by the called listeners are ignored and discarded.
Its implementation is written in C++ and common for all the platforms.
EventEmitterType Methods
| Parameter | Type |
|---|---|
| eventName | EventName |
| listener | TEventsMap[EventName] |
Adds a listener for the given event name.
EventSubscription| Parameter | Type |
|---|---|
| eventName | EventName |
| ...args | Parameters<TEventsMap[EventName]> |
Synchronously calls all the listeners attached to that specific event. The event can include any number of arguments that will be passed to the listeners.
void| Parameter | Type |
|---|---|
| eventName | EventName |
Returns a number of listeners added to the given event.
number| Parameter | Type |
|---|---|
| eventName | keyof TEventsMap |
Removes all listeners for the given event name.
void| Parameter | Type |
|---|---|
| eventName | EventName |
| listener | TEventsMap[EventName] |
Removes a listener for the given event name.
void| Parameter | Type |
|---|---|
| eventName | EventName |
Function that is automatically invoked when the first listener for an event with the given name is added. Override it in a subclass to perform some additional setup once the event started being observed.
voidType: Class extends EventEmitter<TEventsMap>
A class for all native modules. Extends the EventEmitter class.
Type: Class extends EventEmitter<TEventsMap> implements EventEmitter<TEventsMap>
Base class for all shared objects that extends the EventEmitter class.
The implementation is written in C++, installed through JSI and common for mobile platforms.
SharedObjectType Methods
A function that detaches the JS and native objects to let the native object deallocate before the JS object gets deallocated by the JS garbage collector. Any subsequent calls to native functions of the object will throw an error as it is no longer associated with its native counterpart.
In most cases, you should never need to use this function, except some specific performance-critical cases when
manual memory management makes sense and the native object is known to exclusively retain some native memory
(such as binary data or image bitmap). Before calling this function, you should ensure that nothing else will use
this object later on. Shared objects created by React hooks are usually automatically released in the effect's cleanup phase,
for example: useVideoPlayer() from expo-video and useImage() from expo-image.
voidType: Class extends SharedObject<TEventsMap> implements SharedObject<TEventsMap>
A SharedObject that holds a reference to any native object. Allows passing references
to native instances among different independent libraries.
For instance, ImageRef from expo-image references a Drawable
on Android and an UIImage on iOS. Since both types are common on these platforms,
different native modules can use them without depending on each other. In particular, this enables the expo-image-manipulator to pass the resulted image
directly to the image view from expo-image without any additional writes and reads from the file system.
SharedRefType Properties
Methods
Returns a boolean value whether the app is running in Expo Go.
boolean| Parameter | Type | Description |
|---|---|---|
| component | ComponentType<P> | The React component class that renders the rest of your app. |
Sets the initial React component to render natively in the app's root React Native view on Android, iOS, tvOS and the web.
This method does the following:
- Invokes React Native's
AppRegistry.registerComponent. - Invokes React Native web's
AppRegistry.runApplicationon web to render to the rootindex.htmlfile. - Polyfills the
process.nextTickfunction globally.
This method also adds the following dev-only features that are removed in production bundles.
- Adds the Fast Refresh and bundle splitting indicator to the app.
- Asserts if the
expo-updatespackage is misconfigured. - Asserts if
react-nativeis not aliased toreact-native-webwhen running in the browser.
voidSee: For information on how to setup
registerRootComponentin an existing (bare) React Native app, see Common questions below.
| Parameter | Type | Description |
|---|---|---|
| moduleImplementation | ModuleType | A class that extends |
| moduleName | string | – a name to register the module under |
Registers a web module.
ModuleTypeA singleton instance of the class passed into arguments.
| Parameter | Type | Description |
|---|---|---|
| reason(optional) | string | The reason for reloading the app. This is used only for some platforms. |
Reloads the app. This method works for both release and debug builds.
Unlike Updates.reloadAsync(),
this function does not use a new update even if one is available. It only reloads the app using the same JavaScript bundle that is currently running.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| moduleName | string | Name of the requested native module. |
Imports the native module registered with given name. In the first place it tries to load the module installed through the JSI host object and then falls back to the bridge proxy module. Notice that the modules loaded from the proxy may not support some features like synchronous functions.
ModuleTypeObject representing the native module.
| Parameter | Type |
|---|---|
| moduleName | string |
| viewName(optional) | string |
A drop-in replacement for requireNativeComponent.
React.ComponentType<P>| Parameter | Type | Description |
|---|---|---|
| moduleName | string | Name of the requested native module. |
Imports the native module registered with the given name. The same as requireNativeModule,
but returns null when the module cannot be found instead of throwing an error.
ModuleType | nullObject representing the native module or null when it cannot be found.
Event Subscriptions
| Parameter | Type | Description |
|---|---|---|
| eventEmitter | EventEmitter<TEventsMap> | An object that emits events. For example, a native module or shared object or an instance of |
| eventName | TEventName | Name of the event to listen to. |
| listener | TEventListener | A function to call when the event is dispatched. |
React hook that listens to events emitted by the given object and calls the listener function whenever a new event is dispatched. The event listener is automatically added during the first render and removed when the component unmounts.
voidExample
import { useEventListener } from 'expo'; import { useVideoPlayer, VideoView } from 'expo-video'; export function VideoPlayerView() { const player = useVideoPlayer(videoSource); useEventListener(player, 'playingChange', ({ isPlaying }) => { console.log('Player is playing:', isPlaying); }); return <VideoView player={player} />; }
Types
常见问题
🌐 Common questions
关于在你的项目中使用 expo 包的一些常见问题。
🌐 Some common questions about using the expo package in your project.
rootRegisterComponent 为现有的 React Native 项目设置
如果你正在手动管理你的 React Native 项目的原生目录(android 和 ios),你需要按照下面的说明来设置 registerRootComponent 功能。这对于 Expo 模块的正常工作是必要的。
🌐 If you are managing your React Native project's native directories (android and ios) manually, you need to follow the instructions below to set up the registerRootComponent function. This is necessary for the Expo modules to work correctly.
安卓
更新 android/app/src/main/your-package/MainActivity.java 文件,在 getMainComponentName 函数中使用名称 main。
🌐 Update the android/app/src/main/your-package/MainActivity.java file to use the name main in the getMainComponentName function.
@Override protected String getMainComponentName() { + return "main"; }
iOS
更新 iOS 的 ios/your-project/AppDelegate.(m|mm|swift) 文件,在 application:didFinishLaunchingWithOptions: 函数的 createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps 行中使用 moduleName main。
🌐 Update the iOS ios/your-project/AppDelegate.(m|mm|swift) file to use the moduleName main in the createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps line of the application:didFinishLaunchingWithOptions: function.
如果我想给我的主应用文件起一个不是 App.js 或 app/_layout.tsx 的名字怎么办?
对于不使用 Expo Router 的项目,你可以在 package.json 中将 "main" 设置为项目中的任意文件。如果你这么做,那么你需要使用 registerRootComponent。如果你使用自定义入口文件,export default 不会将此组件设为应用的根组件。
例如,假设你想把 src/main.jsx 设置为你的应用入口文件——也许你不想在项目根目录下放置 JavaScript 文件。首先,在 package.json 中进行如下设置:
🌐 For example, let's say you want to make src/main.jsx the entry file for your app — maybe you don't like having JavaScript files in the project root. First, set this in package.json:
{ "main": "src/main.jsx" }
然后,在 src/main.jsx 中,确保你调用 registerRootComponent 并传入你想在应用根部渲染的组件:
🌐 Then, in src/main.jsx, make sure you call registerRootComponent and pass in the component you want to render at the root of the app:
import { registerRootComponent } from 'expo'; import { View } from 'react-native'; function App() { return <View />; } registerRootComponent(App);
对于使用 Expo Router 的项目,你可以按照 Expo Router 安装指南 中的步骤创建自定义入口点。要在你的 Expo Router 项目中使用顶层 src 目录,请参阅 src 目录参考 了解更多信息。