如何在Expo Router的React Native模态框中向父页面传递数据
解决方案
针对你这种模态框关闭后回传数据的场景,这里有几种实用的实现方式:
方法1:利用Expo Router的router.back()传参 + useFocusEffect监听页面激活
这是最贴合Expo Router路由逻辑的方案:
- 页面b(create-account/index.jsx):关闭模态框时通过
router.back()的第二个参数传递数据
import { router } from 'expo-router'; // 提交表单时的处理函数 const handleCreateAccount = (formData) => { // 把要回传的数据通过router.back传递 router.back(null, { newAccountInfo: formData }); // 关闭模态框 };
- 页面a((tabs)/account/index.jsx):用
useFocusEffect监听页面重新激活(模态框关闭后页面a会重新获得焦点),再读取返回的参数
import { useFocusEffect } from '@react-navigation/native'; import { useRouter } from 'expo-router'; import { useState, useCallback } from 'react'; export default function AccountScreen() { const [newAccount, setNewAccount] = useState(null); const router = useRouter(); useFocusEffect( useCallback(() => { // 从路由状态里取出回传的参数 const returnedData = router.getState().route.params?.newAccountInfo; if (returnedData) { setNewAccount(returnedData); // 这里可以做后续处理,比如更新页面展示、发起接口请求等 } }, [router]) ); // 页面渲染逻辑... }
方法2:全局状态管理(Context API / Zustand)
如果后续需要在更多页面共享这类数据,全局状态管理会更方便:
以Context API为例:
- 创建Context文件(比如
contexts/AccountContext.jsx)
import { createContext, useContext, useState } from 'react'; const AccountContext = createContext(); export function AccountProvider({ children }) { const [newAccountData, setNewAccountData] = useState(null); return ( <AccountContext.Provider value={{ newAccountData, setNewAccountData }}> {children} </AccountContext.Provider> ); } export function useAccount() { return useContext(AccountContext); }
- 在根布局
_layout.jsx中包裹Provider
import { AccountProvider } from '../contexts/AccountContext'; export default function RootLayout() { return ( <AccountProvider> {/* 你的路由组件 */} </AccountProvider> ); }
- 页面b中更新全局状态
import { useAccount } from '../contexts/AccountContext'; import { router } from 'expo-router'; const handleSubmit = (formData) => { const { setNewAccountData } = useAccount(); setNewAccountData(formData); router.back(); };
- 页面a中监听状态变化
import { useAccount } from '../contexts/AccountContext'; import { useEffect } from 'react'; export default function AccountScreen() { const { newAccountData } = useAccount(); useEffect(() => { if (newAccountData) { // 处理回传的数据 console.log('收到新账户数据:', newAccountData); } }, [newAccountData]); // 页面渲染逻辑... }
方法3:临时存储(AsyncStorage)
适合不需要实时同步、数据量小的场景:
- 页面b:提交时把数据存入本地存储
import AsyncStorage from '@react-native-async-storage/async-storage'; import { router } from 'expo-router'; const handleSubmit = async (formData) => { await AsyncStorage.setItem('tempAccountData', JSON.stringify(formData)); router.back(); };
- 页面a:监听页面激活时读取并清理临时存储
import AsyncStorage from '@react-native-async-storage/async-storage'; import { useFocusEffect } from '@react-navigation/native'; import { useState, useCallback } from 'react'; export default function AccountScreen() { const [accountData, setAccountData] = useState(null); useFocusEffect( useCallback(async () => { const tempData = await AsyncStorage.getItem('tempAccountData'); if (tempData) { setAccountData(JSON.parse(tempData)); // 读取后删除临时存储,避免重复读取 await AsyncStorage.removeItem('tempAccountData'); } }, []) ); // 页面渲染逻辑... }
内容的提问来源于stack exchange,提问作者David Henry
相关产品推荐
相关产品推荐

