我們經(jīng)常會有返回上一頁并刷新上頁數(shù)據(jù)的功能需求镣典,比如在表單修改完數(shù)據(jù)再返回信息展示頁。在React Native結(jié)合React Navigation 5.x開發(fā)的應用中兄春,我們可以這樣實現(xiàn):
A頁面跳轉(zhuǎn)B頁面時赶舆,在params加上一個值為更新A頁面方法的參數(shù):navigation.navigate('A', { update: () => updateFun()}) }
要從B頁面返回A頁面時,先從路由參數(shù)中獲取這個方法并執(zhí)行芜茵,再返回。
route.params.update()
navigation.goBack()
簡單示例如下:
這是信息展示頁 UserCenter
// 用戶信息展示頁
import React from 'react'
import { View, Button } from 'react-native'
const UserCenter = (props) => {
const updateData = () => {
// ... 這里寫更新頁面的邏輯绞佩,比如重新請求
console.warn('更新數(shù)據(jù)啦')
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="去用戶編輯頁"
onPress={() => props.navigation.navigate('UserEdit', {update: updateData})}
/>
</View>
}
export default UserCenter
這是信息編輯頁 UserEdit
// 用戶信息編輯頁
import React from 'react'
import { View, Button, Alert } from 'react-native'
import { editUser } from '@api/user'
const UserEdit = (props) => {
// 組件狀態(tài)信息省略
const [editInfo, setEditInfo] = useState({......})
const submitEdit = async () => {
// 具體提交請求省略
const result = await editUser(userId, editInfo)
if(result.code === 200) {
Alert.alert(result.message)
// 路由參數(shù) update 的值即是在 UserCenter 組件中定義的 updateData 方法品山,我們直接執(zhí)行它
route.params.update()
navigation.goBack() // 返回上一頁
}
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="確認修改"
onPress={submitEdit}
/>
</View>
}
export default UserEdit
注意:在路由參數(shù)內(nèi)傳遞不可序列化的值(如實例烤低、函數(shù)等)會報一個警告??:Non-serializable values were found in the navigation state
,因為這可能會破壞其他功能扑馁,例如狀態(tài)持久性,深層鏈接等魄懂。
如果你不使用狀態(tài)持久性或不使用接受參數(shù)形式的屏幕的深層鏈接闯第,則可以放心地忽略它。
或者我們安全起見用以下方法:官網(wǎng)鏈接??:傳遞參數(shù)到上一個屏幕
如果目標屏幕已經(jīng)存在于歷史記錄中咳短,我們要實現(xiàn)返回并傳參可以使用navigate
來代替goBack
。這種情況navigate
和goBack
的作用是一樣的篡腌。
為什么它倆可以一樣呢勾效?
順便加深理解下navigate
和push
的區(qū)別:使用navigate
導航到一個已經(jīng)存在于歷史記錄的屏幕的效果是:返回到這個屏幕并刪除在這屏之后的所有記錄叛甫。navigate
永遠不會重復推送相同的屏幕到歷史記錄里杨伙。要實現(xiàn)重復推送,例如傳不同id就表示不同屏幕的詳情頁組件限匣,我們導航的時候必須要用push
。
import React, { useEffect } from 'react'
import { View, Button } from 'react-native'
function UserCenter({ navigation, route }) {
useEffect(() => {
if (route.params?.refresh) {
// 如果拿到了更新參數(shù)锌历,即表示需要刷新
// 這里書寫更新邏輯
console.warn(route.params.refresh)
}
}, [route.params?.refresh])
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="去用戶編輯頁"
onPress={() => navigation.navigate('UserEdit')}
/>
</View>
);
}
function UserEdit({ navigation, route }) {
// 組件狀態(tài)信息省略
const [editInfo, setEditInfo] = useState({......})
const submitEdit = async () => {
// 具體提交請求省略
const result = await editUser(userId, editInfo)
if(result.code === 200) {
Alert.alert(result.message)
// 傳遞個表示要刷新的路由參數(shù)即可峦筒,為了參數(shù)每次變化,我們傳個隨機數(shù)
navigation.navigate('User', { refresh: Math.random() })
}
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="確認修改"
onPress={submitEdit}
/>
</View>
);
}