狀態延存性
您可能希望在應用程式中儲存使用者的位置,這樣他們在重新啟動應用程式後就能立即回到同一個位置。
在開發階段來說,這特別有價值,因為這讓開發人員在重新整理應用程式時仍能待在同一個畫面。
用法
為了保有 導覽狀態,我們可以使用這個容器的 onStateChange
和 initialState
屬性。
onStateChange
- 這個屬性會在任何狀態變更時通知我們。我們可以在這個回呼函式中保留狀態。initialState
- 這個屬性讓我們傳入用於 導覽狀態 的初始狀態。我們可以在這個屬性中傳入還原的狀態。
import * as React from 'react';
import { Linking, Platform } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { NavigationContainer } from '@react-navigation/native';
const PERSISTENCE_KEY = 'NAVIGATION_STATE_V1';
export default function App() {
const [isReady, setIsReady] = React.useState(Platform.OS === 'web'); // Don't persist state on web since it's based on URL
const [initialState, setInitialState] = React.useState();
React.useEffect(() => {
const restoreState = async () => {
try {
const initialUrl = await Linking.getInitialURL();
if (initialUrl == null) {
// Only restore state if there's no deep link
const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
const state = savedStateString
? JSON.parse(savedStateString)
: undefined;
if (state !== undefined) {
setInitialState(state);
}
}
} finally {
setIsReady(true);
}
};
if (!isReady) {
restoreState();
}
}, [isReady]);
if (!isReady) {
return null;
}
return (
<NavigationContainer
initialState={initialState}
onStateChange={(state) =>
AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
}
>
{/* ... */}
</NavigationContainer>
);
}
開發模式
這個功能對於開發模式特別有用。您可以使用下列方式選擇性地啟用它
const [isReady, setIsReady] = React.useState(__DEV__ ? false : true);
儘管它也可以用於製作,但請小心使用,因為如果應用程式在某個特定螢幕上崩潰,它可能會讓應用程式無法使用,因為使用者在重新啟動後仍然會在同一個螢幕上。
載入檢視
由於狀態會非同步復原,應用程式必須簡短地呈現一個空白/載入檢視,才能有初始狀態。要處理這個問題,我們可以在 isReady
為 false
時傳回一個載入檢視
if (!isReady) {
return <ActivityIndicator />;
}
警告:可序列化的狀態
每個參數、路由,以及導覽狀態都必須完全可序列化,這項功能才能運作。一般來說,您會將狀態序列化成 JSON 字串。這表示您的路由和參數不得包含任何函式、類別實例,或遞迴資料結構。如果 React Navigation 遇到不可序列化的資料,會在開發過程中 向您發出警告,因此,如果您計畫保留導覽狀態,請注意警告。
您可以在傳遞到容器之前修改初始狀態物件,但請注意,如果您的 initialState
不是 有效的導覽狀態,React Navigation 可能無法妥善處理情況。