Search code examples
react-nativereduxreact-hooksredux-sagareact-navigation-v5

How to make navigation, when a redux state changes in redux saga with react navigation v5?


How can I navigate the screen when changing the state in Redux-saga ??

My problem is i don't know how to navigate screen from reducer or saga files using react navigation v5

here is my code :

sagaFile.js

// sagaFile.js

function* postingMobileData(data) {
    try {
        const responseData = yield call(postMobile, data);
        yield put({type: SAVE_MOBILE_RESPONSE, responseData});        
        
    } catch (e) {

    }
}


export function* post_mobile() {
    yield takeLatest(POST_MOBILE_DATA, postingMobileData);
}

reducer.js

// reducer.js

export default function (state = initialState, action) {
    switch (action.type) {
        case SAVE_MOBILE_RESPONSE:
            return {
                ...state,
                mobileRes : action.responseData
            }

        default:
            return {
                ...state
            }
    }
}

navigationStack.js

//navigationStack.js

import React from "react";
import Login from "../container/LoginContainer";
import Registration from "../container/RegistrationContainer";
import OtpVerification from "../container/otpVerificationContainer";

import { createStackNavigator } from "@react-navigation/stack";
import { NavigationContainer } from "@react-navigation/native";

const Stack = createStackNavigator();

Navigator = () => {

    return (
        <NavigationContainer>
            <Stack.Navigator
                screenOptions={{
                    headerShown: false
                }}>
                <Stack.Screen name="Login" component={Login} />
                <Stack.Screen name="Registration" component={Registration} />
                <Stack.Screen name="OtpVerification" component={OtpVerification} />
            </Stack.Navigator>
        </NavigationContainer>
    )
}

export default Navigator;
react-native version : 0.63.1
redux-saga version : 1.1.3
react-navigation version : 5.7

I want to change screen, when calling postingMobileData(data) in sagaFile.js

If there is any way, can you tell me one?


Solution

  • I am doing this in my application by following this guide on Rect Navigation, Navigating without the navigation prop.

    This is what I do:

    // App.js

    import { navigationRef } from './NavigationService';
    import { NavigationContainer } from '@react-navigation/native';
    
    const Stack = createStackNavigator();
    
    const App = () => (
        <NavigationContainer ref={navigationRef}>
           <Stack.Navigator
                    screenOptions={{
                        headerShown: false
                    }}>
                    <Stack.Screen name="Login" component={Login} />
                    <Stack.Screen name="Registration" component={Registration} />
                    <Stack.Screen name="OtpVerification" component={OtpVerification} />
                </Stack.Navigator>
        </NavigationContainer>
    )
    
    export default App
    

    // Navigation Service

    import { createRef } from 'react';
    
    export const navigationRef = createRef();
    export const isMountedRef = createRef();
    export const routeNameRef = createRef();
    
    const navigate = (name, params) => {
      if (isMountedRef.current && navigationRef.current) {
        return navigationRef.current.navigate(name, params);
      } else {
        console.error('!!!!not mounted yet!!!!!!!');
      }
    };
    
    const reset = (name, params) => {
      if (isMountedRef.current && navigationRef.current) {
        return navigationRef.current.reset({
          index: 0,
          routes: [
            {
              name,
              params,
            },
          ],
        });
      } else {
        console.error('!!!!not mounted yet!!!!!!!');
      }
    };
    
    export default {
      navigate,
      reset,
      routeNameRef,
    };
    

    // Saga

    import NavigationService from '../NavigationService';
    
    function* postingMobileData(data) {
        try {
            const responseData = yield call(postMobile, data);
            yield put({type: SAVE_MOBILE_RESPONSE, responseData}); 
            yield NavigationService.navigate('OtpVerification');       
            
        } catch (e) {
    
        }
    }