【问题标题】:Ways to put react navigation in Redux Saga Function在 Redux Saga 函数中放置反应导航的方法
【发布时间】:2021-11-06 14:07:53
【问题描述】:

我尝试关注docs 关于在 redux saga 中间件中使用 React 导航。

到目前为止,在我拥有所有屏幕的AppNavigator.tsx 文件中,我使用了navigationRef,如下所示:

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {navigationRef} from './RootNavigation';

const Stack = createStackNavigator();

import LoginScreen from '../src/screens/LoginScreen';
import RegisterScreen from '../src/screens/RegisterScreen';
import HomeScreen from '../src/screens/HomeScreen';

interface Props {}

const AppNavigator: React.FC<Props> = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="LoginScreen"
          component={LoginScreen}
          options={{headerShown: false}}
        />
        <Stack.Screen
          name="RegisterScreen"
          component={RegisterScreen}
          options={{title: 'Create account', headerBackTitle: 'Sign In'}}
        />
        <Stack.Screen
          name="HomeScreen"
          ref={navigationRef}
          component={HomeScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default AppNavigator;

注意主屏幕上的ref={navigationRef}

然后我创建了RootNavigation.js 并把 ff:

import {createNavigationContainerRef} from '@react-navigation/native';

export const navigationRef = createNavigationContainerRef();

export function navigate(name, params) {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

最后,在我的 redux saga 文件中:

export function* onSignIn({payload}) {
  try {
      const response = yield call(loginUserCall, payload);
      if (response.data.user && response.data.token.api_token) {
        yield call(setToken(response.data.token.api_token));
        RootNavigation.navigate('HomeScreen');
      }
    } else {
      yield put(authenticateError({payload: 'No Internet'}));
    }
  } catch (error) {
     // do some error
  } finally {
    // do something else
  }
}

注意这行代码:RootNavigation.navigate('HomeScreen');。这个还是不行。我也尝试像这样同时使用callput

yield call(RootNavigation.navigate('HomeScreen'));
yield put(RootNavigation.navigate('HomeScreen'));

但这些都没有将我的登录屏幕重定向到主屏幕。

知道如何正确执行此操作吗?

更新:我什至尝试在 stackoverflow 中关注这个线程 here 并这样做:

// LoginScreen.tsx

const LoginScreen: React.FC<Props> = navData => {
  const navigateTo = (destinationScreen: string) =>
    navData.navigation.navigate(destinationScreen);

  const dispatch = useDispatch();

  const submitHandler = (val: any) => {
    dispatch(signInStart(val, navData.navigation));
  };

然后是我的行动:

export const signInStart = (userInput, navigation) => {
  return {
    type: type.SIGN_IN_START,
    payload: {userInput, navigation},
  };
};

关于我的传奇:

export function* onSignIn({payload}) {
  try {
      const response = yield call(loginUserApi, payload);
      if (response.data.user && response.data.token.api_token) {
        console.log('token >>', response.data.token.api_token);
        yield call(setToken(response.data.token.api_token));
        yield call(navigation.navigate, 'HomeScreen');
      }
    } else {

    }
  } 

还是没有运气。

【问题讨论】:

  • 您是否尝试过通过动作有效负载将 navigation prop 从组件级别解析为 saga 生成器函数?
  • 我该怎么做?请提供示例。
  • 你有什么错误吗?顺便说一句,与 call - yield call(RootNavigation.navigate, 'HomeScreen'); 一起使用
  • 同样来自文档,参考应该附加到NavigationContainer 而不是“HomeScreen”:&lt;NavigationContainer ref={navigationRef}&gt; ...
  • @Alekysey L. 尝试在我的 redux saga 函数上使用 yield call(RootNavigation.navigate, 'HomeScreen'); 并修复了 &lt;NavigationContainer ref={navigationRef}&gt;

标签: react-native react-navigation redux-saga


【解决方案1】:

您非常接近以正确的方式做到这一点。拨打navigationRef

类似的东西。

   navigationRef.navigate("HomeScreen")

还有ref 应该是 NavigationContainer ref

import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';

export default function App() {
  return (
    <NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
  );
}

【讨论】:

  • 我需要像这样在我的 redux saga 文件中包含 RootNavigation 吗? import * as RootNavigation from '../../navigations/RootNavigation';
  • 我认为它与调用yield call(RootNavigation.navigate, 'HomeScreen'); 相同,但它也不起作用。
  • 你可以直接打电话。你不需要yield call
猜你喜欢
  • 2018-04-15
  • 2020-12-24
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 2018-05-16
  • 2018-06-04
  • 1970-01-01
相关资源
最近更新 更多