跳至主要内容
版本: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 可能无法优雅地处理这种情况。