跳到主內容
版本:6.x

狀態延存性

您可能希望在應用程式中儲存使用者的位置,這樣他們在重新啟動應用程式後就能立即回到同一個位置。

在開發階段來說,這特別有價值,因為這讓開發人員在重新整理應用程式時仍能待在同一個畫面。

用法

為了保有 導覽狀態,我們可以使用這個容器的 onStateChangeinitialState 屬性。

  • 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);

儘管它也可以用於製作,但請小心使用,因為如果應用程式在某個特定螢幕上崩潰,它可能會讓應用程式無法使用,因為使用者在重新啟動後仍然會在同一個螢幕上。

載入檢視

由於狀態會非同步復原,應用程式必須簡短地呈現一個空白/載入檢視,才能有初始狀態。要處理這個問題,我們可以在 isReadyfalse 時傳回一個載入檢視

if (!isReady) {
return <ActivityIndicator />;
}

警告:可序列化的狀態

每個參數、路由,以及導覽狀態都必須完全可序列化,這項功能才能運作。一般來說,您會將狀態序列化成 JSON 字串。這表示您的路由和參數不得包含任何函式、類別實例,或遞迴資料結構。如果 React Navigation 遇到不可序列化的資料,會在開發過程中 向您發出警告,因此,如果您計畫保留導覽狀態,請注意警告。

您可以在傳遞到容器之前修改初始狀態物件,但請注意,如果您的 initialState 不是 有效的導覽狀態,React Navigation 可能無法妥善處理情況。