【问题标题】:Persist state with react-navigation AppContainer使用 react-navigation AppContainer 保持状态
【发布时间】:2019-10-28 10:42:42
【问题描述】:

我将 react-native 项目的 react-navigation 从 v2.x 更新到 v3.x。对于 v2.x,我在根目录下渲染了这个:

const AppNavigator = createStackNavigator({...})

const App = () => <AppNavigator persistenceKey={"NavigationState"} />;

export default App; 

我需要保持状态,这就是我使用persistenceKey的原因

对于 react-navigation 的 v3.x,需要一个应用容器,但我在弄清楚如何实现相同的状态持久性时遇到了问题。

这是我的 v3.x 新代码

const AppNavigator = createStackNavigator({...})

const AppContainer = createAppContainer(AppNavigator)

const App = () => <AppContainer />;

export default App;

如何以这种方式保持状态?

谢谢

编辑:

我试过了:

const AppNavigator = createStackNavigator({...})

const persistenceKey = "persistenceKey"
  const persistNavigationState = async (navState) => {
    try {
      await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
    } catch(err) {
      // handle the error according to your needs
    }
  }
  const loadNavigationState = async () => {
    const jsonString = await AsyncStorage.getItem(persistenceKey)
    return JSON.parse(jsonString)
  }

const AppNavigationPersists = () => <AppNavigator
  persistNavigationState={persistNavigationState}
  loadNavigationState={loadNavigationState}
/>

const AppContainer = createAppContainer(AppNavigationPersists)

export default AppContainer;

但我收到此错误:

Cannot read property 'getStateForAction' of undefined

【问题讨论】:

    标签: javascript reactjs react-native react-navigation


    【解决方案1】:

    如果您使用带有反应导航 4 的 createAppContainer,这是对我有用的解决方案。

    const App: () => React$Node = () => {
    
        const persistenceKey = "persistenceKey"
        const persistNavigationState = async (navState) => {
            try {
                await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
            } catch(err) {
                // handle error
            }
        }
        const loadNavigationState = async () => {
            const jsonString = await AsyncStorage.getItem(persistenceKey)
            return JSON.parse(jsonString)
        }
        return(
            <View style={{flex: 1, backgroundColor: '#000000'}}>
                <AppContainer
                    persistNavigationState={persistNavigationState}
                    loadNavigationState={loadNavigationState}
                />
            </View>
        );
    };
    

    【讨论】:

    • 嗨,你能看看这个问题吗?有人建议我在应用程序来自前台时使用反应导航来保持导航状态,但我不知道如何在我当前的实现之上实现。 stackoverflow.com/questions/66548327/…
    【解决方案2】:

    文档不清楚,但您实际上需要将道具persistNavigationStateloadNavigationState直接传递给AppContainer组件:

    <AppContainer
      persistNavigationState={persistNavigationState}
      loadNavigationState={loadNavigationState}
    />
    

    【讨论】:

      【解决方案3】:

      您可能需要将react-navigation 更新为&gt;= 3.10.0

      根据react-navigation changelog,他们现在只支持react-navigation@^3.10 上的persistNavigationStateloadNavigationState

      您仍然可以在低于3.10 的版本上使用persistenceKey

      ---编辑---

      &lt;3.10.0 版本示例:

      const AppNavigator = createStackNavigator({...})
      
      const App = () => <AppNavigator persistenceKey={"NavigationState"} />;
      
      export default App; 
      

      &gt;= 3.10.0 版本的示例实现:

      const AppNavigator = createStackNavigator({...});
      const persistenceKey = "persistenceKey"
      const persistNavigationState = async (navState) => {
        try {
          await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
        } catch(err) {
          // handle the error according to your needs
        }
      }
      const loadNavigationState = async () => {
        const jsonString = await AsyncStorage.getItem(persistenceKey)
        return JSON.parse(jsonString)
      }
      
      const App = () => <AppNavigator persistNavigationState={persistNavigationState} loadNavigationState={loadNavigationState} />;
      

      【讨论】:

      • 我按照您的建议使用了最新的 v2.x 版本。谢谢!
      • 这并不能解决问题。您可以使用 React Navigation 3.10 及更高版本来保持状态,但如何将其与 createAppContainer 结合使用尚不清楚,不幸的是,这是 Google 上的顶级结果。
      • @Slbox 澄清一下,persistenceKey 已被两个函数取代,persistNavigationStateloadNavigationStatepersistNavigationState 接收当前导航状态作为参数,您需要实现导航状态的存储 loadNavigationState 不接收任何参数,需要以 JSON 形式返回导航状态
      • 感谢您编辑这篇文章!从长远来看,它会为很多人节省大量时间。
      【解决方案4】:

      只需按照与示例中相同的方式实现即可。在我的情况下,我忘记将 react-navigation 更新到版本 ^3.11.0,我也忘记导入 AsyncStorage。不知何故,本机反应并没有抱怨 AsyncStorage 不存在。这就是为什么状态持久性似乎不起作用的原因。

      import {
        AsyncStorage
      } from "react-native";
      
      const AppNavigator = createStackNavigator({...});
      
      const AppContainer = createAppContainer(AppNavigator);
      
      const persistenceKey = "persistenceKey"
      
      const persistNavigationState = async (navState) => {
        try {
          await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
        } catch(err) {
          // handle the error according to your needs
        }
      }
      
      const loadNavigationState = async () => {
        const jsonString = await AsyncStorage.getItem(persistenceKey)
        return JSON.parse(jsonString)
      }
      
      const App = () => <AppContainer persistNavigationState={persistNavigationState} loadNavigationState={loadNavigationState}  renderLoadingExperimental={() => <ActivityIndicator />}/>;
      

      【讨论】:

        【解决方案5】:

        您可以查看docs example for v3.x

        const AppNavigator = createStackNavigator({...});
          const persistenceKey = "persistenceKey"
          const persistNavigationState = async (navState) => {
            try {
              await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
            } catch(err) {
              // handle the error according to your needs
            }
          }
          const loadNavigationState = async () => {
            const jsonString = await AsyncStorage.getItem(persistenceKey)
            return JSON.parse(jsonString)
          }
        
         const App = () => <AppNavigator persistNavigationState={persistNavigationState} loadNavigationState={loadNavigationState} />;
        

        要解决const AppContainer = createAppContainer(AppNavigator) 中的问题,您可以做的是创建另一个返回AppNavigator 并具有持久性的组件。

        const AppNavigationPersists = () => <AppNavigator 
            persistNavigationState={persistNavigationState} 
            loadNavigationState={loadNavigationState} 
        />
        const AppContainer = createAppContainer(AppNavigationPersists)
        

        【讨论】:

        • 我听从了您的建议,但收到此错误:Cannot read property 'getStateForAction' of undefined。与 NavigationContainer 相关
        • 嗯,这很奇怪,不知道如何帮助更多
        • 我只用 const AppNavigator = createAppContainer( createStackNavigator({...}) );
        • 当我将 persistNavigationStateloadNavigationState 传递给 AppContainer 而不是 AppNavigator 时,它对我有用。
        • 嗨,你能看看这个问题吗?有人建议我在应用程序来自前台时使用反应导航来保持导航状态,但我不知道如何在我当前的实现之上实现。 stackoverflow.com/questions/66548327/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-03
        • 2022-08-21
        • 1970-01-01
        • 2020-10-26
        • 2017-08-28
        • 2023-03-26
        相关资源
        最近更新 更多