在普通功能内使用react react.navigate-(不允许使用钩子,即useNavigation)?

时间:2020-02-29 08:35:59

标签: reactjs react-native react-navigation react-native-navigation

我正在尝试将一个导航到另一个模块中的屏幕的函数并将其导出,但是navigation不起作用。我尝试使用UseNavigation(),但遇到错误,即:Unhandled promise rejection: Invariant Violation: Hooks can only be called inside the body of a function component.

是否可以在常规功能或其他任何功能中使用导航。

import React, { useState, useEffect, useCallback } from "react";
import { AsyncStorage, Alert } from "react-native";
import { useNavigation } from "react-navigation-hooks";

export const startMixGame = async (categoryIsChosen, withTimer) => {
  const navigation = useNavigation();

  if (categoryIsChosen) {
    if (withTimer) {
      await AsyncStorage.setItem("useTimer", "true");
      navigation.navigate({
        routeName: "MixedQuestions",
        params: {
          categoryId: "1"
        }
      });
    } else if (!withTimer) {
      // console.log("withTimer", withTimer);

      await AsyncStorage.setItem("useTimer", "false");
      navigation.navigate({
        routeName: "NoTimerMixedQuestions",
        params: {
          categoryId: "1"
        }
      });
    }
  }

};

谢谢

2 个答案:

答案 0 :(得分:2)

是的,使用单例服务保存对导航的引用,在应用程序的根目录中保存一个useEffect单例中的引用,因此您可以在任何地方使用它。 像这样:

class NavigationService {
  constructor() {
    this._navigation = null;
  }

  set navigation(nav) {
    this._navigation = nav;
  }

  get navigation() {
    return this._navigation;
  }
}

const navigationService = new NavigationService();

export default navigationService;

并在主屏幕/视图中

    const HomeScreen = ({navigation}) => {
      useEffect(() => {
        navigationService.navigation = navigation;
      }, [navigation]);
   ....

现在您可以在任何地方这样做

import navigationService from '../services/navigation';

navigationService.navigation.navigate('Screen');

答案 1 :(得分:0)

检查此 https://reactnavigation.org/docs/navigating-without-navigation-prop/

您可以保存对NavigationContainer的引用,并使用它进行导航。

应用

import AppNavigator from './AppNavigator'
...
render (){
 return (<AppNavigator/>)
}

AppNavigator

import * as React from 'react';
import AppStack from './AppStack';
import {NavigationContainer} from '@react-navigation/native';
import NavigationService from './NavigationService';

const AppNavigator = () => {
    return (
        <NavigationContainer
            ref={NavigationService.instance}
        >
            <AppStack/>
        </NavigationContainer>
    );
};
export default AppNavigator

AppStack

import {createStackNavigator} from '@react-navigation/stack';

const Stack = createStackNavigator();


export default () => {
    return (
        <Stack.Navigator>

             // add all screens here
             <Stack.Screen
                name={'Home'}
                component={HomeCpmponent}
            />

        </Stack.Navigator>
    )
}
import {NavigationContainerRef} from '@react-navigation/native';
import * as React from 'react';
import {boundClass} from 'autobind-decorator';

@boundClass
class NavigationService {
    instance = React.createRef<NavigationContainerRef>();

    dispatch(action) {
        this.instance.current?.dispatch(action)
    }

    getInstance() {
        return this.instance?.current
    }

    canGoBack() {
        return this.getInstance()?.canGoBack()
    }

    navigate(routeName: string, params: any) {
        return this.getInstance()?.navigate(routeName, params)
    }

}

export default new NavigationService()

您可以使用NavigationService.dispatch()import {CommonActions, StackActions} from '@react-navigation/native'; NavigationService.navigate('home',{id:'test1'})或...