Использовать реагирующую навигацию.navigate внутри обычной функции - (никакие зацепки не разрешены, т.е. - PullRequest
1 голос
/ 29 февраля 2020

Я пытаюсь поместить функцию, которая перемещается на экран в другом модуле, и экспортировать ее, но 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 ]

1 голос
/ 29 февраля 2020

Да, используйте одноэлементный сервис, содержащий ссылку на навигацию, в root вашего приложения сохраните с помощью 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');
0 голосов
/ 29 февраля 2020

отметьте это 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'}) или ...

...