RN主机视图

一个允许在 Jetpack Compose 内使用 React Native 视图的组件。

Android
Bundled version:
~55.0.15

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

一个组件,当 React Native 视图在 Jetpack Compose 组件中渲染时,它可以实现正确的布局行为。它通过更新 Shadow 节点的大小,将布局信息从 Jetpack Compose 同步回 React Native 的 Yoga 布局系统。

🌐 A component that enables proper layout behavior when React Native views are rendered inside Jetpack Compose components. It syncs layout information from Jetpack Compose back to React Native's Yoga layout system by updating the shadow node size.

当 React Native 视图被放置在像 ModalBottomSheetCardRowColumn 等 Jetpack Compose 组件内部时,布局系统需要进行通信。RNHostView 弥合了这一差距:

🌐 When React Native views are placed inside Jetpack Compose components like ModalBottomSheet, Card, Row, Column and so on, the layout systems need to communicate. RNHostView bridges this gap:

  • 使用 matchContents:影子节点的大小设置为匹配子 React Native 视图的内在大小,从而允许 Jetpack Compose 父组件根据 React Native 内容调整自身大小。
  • 没有 matchContents:影子节点的大小设置为与父 Jetpack Compose 视图的大小匹配,从而允许 React Native 内容填充可用空间(对 flex: 1 布局非常有用)。

安装

🌐 Installation

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

用法

🌐 Usage

matchContents 的基本用法

🌐 Basic usage with matchContents

当你希望 Jetpack Compose 的父组件根据 React Native 的内容调整自身大小时,使用 matchContents

🌐 Use matchContents when you want the Jetpack Compose parent to size itself based on the React Native content.

RNHostView with matchContents
import { useState } from 'react'; import { Pressable, Text as RNText, View } from 'react-native'; import { Host, Card, Column, Row, RNHostView, Text } from '@expo/ui/jetpack-compose'; import { fillMaxWidth, padding } from '@expo/ui/jetpack-compose/modifiers'; function Example() { const [counter, setCounter] = useState(0); return ( <Host style={{ flex: 1 }}> <Card modifiers={[fillMaxWidth()]}> <Column verticalArrangement={{ spacedBy: 12 }} modifiers={[padding(16, 16, 16, 16)]}> <Text>Mixing RN Components with Compose</Text> <Row horizontalArrangement={{ spacedBy: 24 }} verticalAlignment="center"> <RNHostView matchContents> <Pressable onPress={() => setCounter(prev => prev - 1)} style={{ height: 50, width: 50, borderRadius: 100, justifyContent: 'center', alignItems: 'center', backgroundColor: '#9B59B6', }}> <RNText style={{ color: 'white', fontSize: 24 }}>-</RNText> </Pressable> </RNHostView> <Text>{counter}</Text> <RNHostView matchContents> <Pressable onPress={() => setCounter(prev => prev + 1)} style={{ height: 50, width: 50, borderRadius: 100, justifyContent: 'center', alignItems: 'center', backgroundColor: '#9B59B6', }}> <RNText style={{ color: 'white', fontSize: 24 }}>+</RNText> </Pressable> </RNHostView> </Row> </Column> </Card> </Host> ); }

没有匹配内容的灵活内容

🌐 Flexible content without matchContents

在你的 React Native 内容中使用 flex: 1 时,省略 matchContents 属性,以便内容填充可用的 Jetpack Compose 空间。

🌐 When using flex: 1 in your React Native content, omit the matchContents prop so the content fills the available Jetpack Compose space.

RNHostView with flex content
import { Text as RNText, View } from 'react-native'; import { Host, Card, Column, Row, RNHostView, Text } from '@expo/ui/jetpack-compose'; import { fillMaxWidth, padding, size } from '@expo/ui/jetpack-compose/modifiers'; function Example() { return ( <Host style={{ flex: 1 }}> <Card modifiers={[fillMaxWidth()]}> <Column verticalArrangement={{ spacedBy: 12 }} modifiers={[padding(16, 16, 16, 16)]}> <Text>RN components with flex: 1 children</Text> <Row horizontalArrangement={{ spacedBy: 20 }} modifiers={[size(100, 100)]}> <RNHostView> <View style={{ flex: 1, backgroundColor: '#9B59B6', borderRadius: 10, }} /> </RNHostView> </Row> </Column> </Card> </Host> ); }

与 ModalBottomSheet 的使用

🌐 Usage with ModalBottomSheet

RNHostViewModalBottomSheet 内部工作良好,可显示互动的 React Native 内容。

RNHostView in ModalBottomSheet
import { useRef, useState } from 'react'; import { Pressable, Text as RNText, View } from 'react-native'; import { Host, ModalBottomSheet, Button, Column, RNHostView, Text } from '@expo/ui/jetpack-compose'; import type { ModalBottomSheetRef } from '@expo/ui/jetpack-compose'; import { padding } from '@expo/ui/jetpack-compose/modifiers'; function Example() { const [visible, setVisible] = useState(false); const sheetRef = useRef<ModalBottomSheetRef>(null); const hideSheet = async () => { await sheetRef.current?.hide(); setVisible(false); }; return ( <Host matchContents> <Button onClick={() => setVisible(true)}> <Text>Open Sheet</Text> </Button> {visible && ( <ModalBottomSheet ref={sheetRef} onDismissRequest={() => setVisible(false)}> <Column verticalArrangement={{ spacedBy: 16 }} modifiers={[padding(16, 16, 16, 16)]}> <Text>Mixing Compose + RN in a Bottom Sheet</Text> <RNHostView matchContents> <View> <RNText style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}> React Native Content </RNText> <Pressable style={{ backgroundColor: '#007AFF', padding: 12, borderRadius: 8, alignItems: 'center', }} onPress={hideSheet}> <RNText style={{ color: 'white', fontWeight: '600' }}>Close</RNText> </Pressable> </View> </RNHostView> </Column> </ModalBottomSheet> )} </Host> ); }

底部弹出层中的灵活 React Native 内容

🌐 Flexible React Native content in a bottom sheet

在不使用 matchContents 的情况下使用 RNHostView,使 React Native 视图填充表单内剩余的空间。将其与父 Column 上的 height 修饰符结合使用,以控制表单大小。

🌐 Use RNHostView without matchContents to let the React Native view fill the remaining space inside the sheet. Combine with a height modifier on the parent Column to control the sheet size.

RNHostView flex in ModalBottomSheet
import { useRef, useState } from 'react'; import { Text as RNText, View } from 'react-native'; import { Host, ModalBottomSheet, Button, Column, RNHostView, Text } from '@expo/ui/jetpack-compose'; import type { ModalBottomSheetRef } from '@expo/ui/jetpack-compose'; import { height, padding } from '@expo/ui/jetpack-compose/modifiers'; function Example() { const [visible, setVisible] = useState(false); const sheetRef = useRef<ModalBottomSheetRef>(null); return ( <Host matchContents> <Button onClick={() => setVisible(true)}> <Text>Open Flex Content Sheet</Text> </Button> {visible && ( <ModalBottomSheet ref={sheetRef} onDismissRequest={() => setVisible(false)} skipPartiallyExpanded> <Column modifiers={[height(400), padding(16, 16, 16, 16)]}> <RNHostView> <View style={{ flex: 1, backgroundColor: '#9B59B6', borderRadius: 10 }}> <RNText style={{ color: 'white', fontSize: 18, fontWeight: 'bold', padding: 16, }}> React Native Content (flex: 1) </RNText> </View> </RNHostView> </Column> </ModalBottomSheet> )} </Host> ); }

应用接口

🌐 API

import { RNHostView } from '@expo/ui/jetpack-compose';

Component

RNHostView

Android

Type: React.Element<RNHostProps>

RNHostViewProps

children

Android
Type: ReactElement

The RN View to be hosted.

matchContents

Android
Optional • Type: boolean • Default: false

When true, the RNHost will update its size in the Jetpack Compose view tree to match the children's size. When false, the RNHost will use the size of the parent Jetpack Compose View. Can be only set once on mount.

modifiers

Android
Optional • Type: ModifierConfig[]

Modifiers for the component.

Inherited Props

  • PrimitiveBaseProps