react-nativeexpoexpo-router

Pass params while navigating back


I am using expo-router, I have two screens ScreenA and ScreenB, from ScreenA I am navigating to screenB, in screenB I want to push data back to screenA by using router.back() or any other way, I don't want to use router.push() since I want to go back not push the previous screen on top of the stack, Is there any way to pass params while navigating back in expo-router

Here is the root layout:

 <Stack>
      <Stack.Screen
        name="index"
      />
      <Stack.Screen
        name="admin/screenA"
      />
    </Stack>

Here is how I am navigating to screenB:

router.push({
     pathname: './screenB',
     params: location
     ? {
     latitude: location.latitude,
     longitude: location.longitude, 
}: null,});

I am using useLocalSearchParams() to access params in both screens


Solution

  • Solution 1

    If you do not have Redux integrated in your app, you can use Context from react to share data between the two screens.

    A possible implementation of the context could be as follows:

    import React, {useState} from 'react';
    
    export const SharedContext = React.createContext({
      sharedData: [],
      setSharedData: (val) => {},
    });
    
    export default function SharedDataProvider({children}) {
      const [data, setData] = useState([]);
    
      function setSharedData(value) {
        setData(value);
      }
    
      return (
        <SharedContext.Provider
          value={{
            sharedData: data,
            setSharedData,
          }}>
          {children}
        </SharedContext.Provider>
      );
    }
    

    Then, you can keep screens A & B under the same folder and add a _layout file where you can wrap the screens with the provider.

    import SharedContext from "@/context/SharedContext"
    
    export default function CommonLayout  () {
        return (
            <SharedContext>
                <Stack>
                    <Stack.Screen name="screenA" />
                </Stack>
            </SharedContext>
        )
    }
    

    Then you can set the data in screen B by using the useContext hook:

    import {SharedContext} from '@/context/SharedContext';
    
    const {setSharedData} = useContext(SharedContext);
    
    // Somewhere on the press of a button
    setSharedData([]); // some data
    

    And finally access the data in screen A when you navigate back to it.

    import {SharedContext} from '@/context/SharedContext'
    
    
    const {sharedData} = useContext(SharedContext);
    

    Solution 2

    You could try navigating back to screen A with router.navigate by passing the absolute path of the screen and the params you'd like to send. For instance, in screen B, you can add:

    router.navigate({pathname: 'path-to-screen-A', params: {
          extraParams: {
            
          }
    }})