使用Expo Router v2时如何用RealmProvider包裹整个项目?
问题
我正在使用RealmDB,需要用RealmProvider组件包裹所有组件,请问在使用Expo Router时能否实现该操作?我尝试了如下代码:
return ( <RealmProvider> <View style={styles.container}> <Stack.Screen options={{title: 'Home'}}/> <DeckComponent name='amONGUS' cards={50}/> <Modal transparent={true} animationType="fade" visible={isVisible} onRequestClose={() => {changeVisible(false)}} > <EnterModal name={deckName} changeName={setDeckName} submitEdit={() =>{ console.log(deckName) setIsVisible(false) }}/> </Modal> <View style={styles.bottom}> <TouchableOpacity onPress={() =>{changeVisible(true)}} style={styles.add} ><AntDesign name="plus" size={30}/></TouchableOpacity> </View> </View> </RealmProvider> );
同时在同一文件中使用useRealm钩子,却出现错误:找不到Realm上下文。你是否在RealmProvider内部使用了useRealm()?
解决方案
可以在Expo Router中实现用RealmProvider包裹所有组件,但你当前的写法存在两处关键问题:
- Expo Router的
Stack.Screen属于路由配置项,不能直接在业务组件的JSX中渲染,必须放在根路由布局文件中定义。 - 你在当前文件中调用
useRealm时,代码执行时机早于RealmProvider的渲染——组件在返回JSX前就执行了useRealm,此时Realm上下文还未被注入,因此报错。
正确实现步骤如下:
- 在Expo Router的根布局文件(
app/_layout.js)中包裹RealmProvider,确保所有路由组件都处于上下文范围内:
import { Stack } from 'expo-router'; import { RealmProvider } from '@realm/react'; export default function RootLayout() { return ( <RealmProvider> <Stack> <Stack.Screen name="index" options={{ title: 'Home' }} /> {/* 其他路由屏幕配置 */} </Stack> </RealmProvider> ); }
- 在业务组件(比如
app/index.js)中,移除Stack.Screen的直接渲染,正常使用useRealm:
import { useState } from 'react'; import { View, Modal, TouchableOpacity } from 'react-native'; import { useRealm } from '@realm/react'; import AntDesign from '@expo/vector-icons/AntDesign'; import DeckComponent from './components/DeckComponent'; import EnterModal from './components/EnterModal'; import styles from './styles'; export default function HomeScreen() { const realm = useRealm(); // 现在可正常获取Realm上下文 const [isVisible, setIsVisible] = useState(false); const [deckName, setDeckName] = useState(''); const changeVisible = (visible) => setIsVisible(visible); return ( <View style={styles.container}> <DeckComponent name='amONGUS' cards={50}/> <Modal transparent={true} animationType="fade" visible={isVisible} onRequestClose={() => changeVisible(false)} > <EnterModal name={deckName} changeName={setDeckName} submitEdit={() => { console.log(deckName) setIsVisible(false) }} /> </Modal> <View style={styles.bottom}> <TouchableOpacity onPress={() => changeVisible(true)} style={styles.add}> <AntDesign name="plus" size={30}/> </TouchableOpacity> </View> </View> ); }
- 确保安装了匹配Expo SDK版本的依赖:
@realm/react和realm。
内容的提问来源于stack exchange,提问作者severeconstipation
相关产品推荐
相关产品推荐

