Question
Answer and Explanation
Passing a function between different screens or components within Expo Router can be a bit nuanced since navigation primarily focuses on routes and data. However, you can achieve this using a few different strategies. Here are some recommended methods:
1. Using Context API or State Management Libraries:
- Context API: The React Context API can provide functions that can be shared globally, which makes it perfect to manage a set of functions that many components require, for instance an authentication functions.
- State Management: Libraries such as Redux, Zustand, or Recoil allow functions to be stored in a centralized store and accessible to any connected component.
2. Utilizing `useLocalSearchParams` Hook and Stringification:
- While you cannot pass functions directly through the router parameters, you can encode functions as string, if the use-case permits to this approach, using JSON.stringify
and then use JSON.parse
on the target component, after parsing.
- This is very hacky but useful for small and trivial actions, not meant to carry complex logic with this way.
Example using React Context API:
First, we need to create a context. Create a new file, such as FunctionContext.js
and insert this code:
import React, { createContext, useState } from 'react';
export const FunctionContext = createContext();
export const FunctionProvider = ({ children }) => {
const [myVariable, setMyVariable] = useState('initial value');
const sharedFunction = () => {
setMyVariable("value updated after a function call")
};
return (
<FunctionContext.Provider value={{sharedFunction, myVariable}}>
{children}
</FunctionContext.Provider>
);
};
Now in your root entry point such as _layout.js
or any of your layouts, wrap the whole tree using FunctionProvider
like below:
import { Stack } from "expo-router";
import { FunctionProvider } from './src/FunctionContext';
export default function Layout() {
return (
<FunctionProvider>
<Stack>
</Stack>
</FunctionProvider>
);
}
And in your screens where you will use that sharedFunction or myVariable, just use this code like the one below:
import { View, Button, Text } from "react-native";
import { useContext } from "react";
import { FunctionContext } from "../../src/FunctionContext";
export default function Index() {
const { sharedFunction, myVariable } = useContext(FunctionContext);
return (
<View style={{flex:1, alignItems: 'center', justifyContent:'center' }}>
<Text> {myVariable} </Text>
<Button title='Execute Function' onPress={()=>{sharedFunction()}} ></Button>
</View>
);
}
In the given examples we have seen that the function and shared variables are easy accessible globally to be re-utilized as part of multiple react screens or components
Summary:
In Expo Router, passing functions requires a slightly different strategy than direct passing as parameters through navigation, Context API or dedicated State management tools are great options and have also good patterns that promotes global function use in the application