I am writing a mobile application in react native using expo router.
I currently have a main screen containing content, that has a path to another screen where users can upload content. On calling router.back() which brings the user back to the main screen, I would like the main screen to refresh with the newly updated content.
Currently, I am confused on the how to implement this, and have been trying to use the useContext hook but it has not been working.
My current code is as follows:
Code from MainScreen.tsx responsible for updating content when refresh
is set to true
:
const { refresh, setUser, ...user } = useContext(UserContext); // Destructure the needed parts
const [feedData, setFeedData] = useState<any[]>([]);
const [deleteRefresh, setDeleteRefresh] = useState(false)
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true);
console.log("Use effect called with refresh: ", refresh);
async function getFeedData() {
const newFeed = await logFeedData();
if (newFeed) {
setFeedData(newFeed);
setUser({refresh: false, ...user})
} else {
console.log("No new feed data");
}
}
if (refresh) {
getFeedData();
}
console.log("Now setting loading to false");
setLoading(false);
}, [refresh]);
Code from the Broadcast.tsx screen responsible for the upload of user content:
const { refresh, setUser, ...user } = useContext(UserContext); // Destructure the needed parts
const BroadcastText: React.FC<BroadcastTextProps> = (setUpdated: any) => {
async function postFeedText(content: string, userId: string) {
try {
const response = await post({
//uploads user data
).response;
const jsonData = await response.body.json();
console.log("POST body: ", jsonData)
console.log("Setting user refresh value to true")
setUser({...user, refresh: true})
console.log("Refresh value: ", refresh)
router.back()
return;
} catch (err) {
console.log("err uploading text")
}
}
And I have my user context defined in my top level _layout.tsx file as follows:
import { LogBox } from 'react-native';
import { Stack } from "expo-router"
import { useState, createContext, useEffect } from "react";
export { default as ReactFromModule } from 'react'
import { profileTheme } from './Theme.js';
type UserContextType = {
userName: string,
userEmail: string,
userId: string,
refresh: boolean,
setUser: (user: Partial<UserContextType>) => void,
profilePicPath: string,
profilePicUrl: string
};
// Initialize with default values
const defaultContextValue: UserContextType = {
userName: '',
userEmail: '',
userId: 'default',
refresh: false,
setUser: () => {},
profilePicPath: '',
profilePicUrl: ''
};
export const UserContext = createContext<UserContextType>(defaultContextValue);
export default function RootLayout() {
const [user, setUser] = useState<UserContextType>(defaultContextValue);
const handleSetUser = (userData: Partial<UserContextType>) => {
console.log("Context has been called");
setUser(prevUser => ({
...prevUser,
...userData
}));
};
console.log("ROOT LAYOUT");
return (
<UserContext.Provider value={{ ...user, setUser: handleSetUser }}>
<Stack screenOptions={{ headerShown: false }}>
{/* Your screens */}
</Stack>
</UserContext.Provider>
);
};
If there are issues with the useContext approach, or if there is any other approach that is more efficient/elegant, please let me know. Thank you!