I’ve looked up for hours and I just can’t find any solution for my problem.
I’m developing an app that uses react context and I’m also using react-router-dom to navigate through my pages.
This context file, has a initial state, for I am using useReducer hook to change it.
But when I navigate along application, like changing or switch pages my state realoads and I can’t get data from my state unless I make a new get request.
I’ve read somewhere that react-router-dom is refreshing my pages so I can’t make it.
Is there any tip you guys can give me?
Actually I can’t think about a solution since I am confusing about how do I make the state "permanent"
there is my index:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { AppProvider } from "./context";
import "./styles.css";
import Login from "./pages/Login";
import Profile from "./pages/Profile";
import Register from "./pages/Register";
import FriendshipAccess from "./pages/FriendshipAccess";
import SearchPage from "./pages/SearchPage";
import EditAccount from "./pages/EditAccount";
ReactDOM.render(
<React.StrictMode>
<AppProvider>
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Login />} />
<Route path="/profile" element={<Profile />} />
<Route path="/account/edit" element={<EditAccount />} />
<Route path="/register" element={<Register />} />
<Route path="/users/:nickname" element={<FriendshipAccess />} />
<Route path="/users/search" element={<SearchPage />} />
</Routes>
</BrowserRouter>
</AppProvider>
</React.StrictMode>,
document.getElementById("root")
);
Here is my context:
import React, { useContext, useReducer } from "react";
import reducer from "./reducer";
import {
registerNewUser,
authUser, //MARKDOWN OF THE TASK!!!!!
getUserPosts,
accessUserProfile,
validateUserToken,
editAccountData,
} from "./operations/operations";
const AppContext = React.createContext();
const initialState = {
userState: {
userData: {},
userPosts: [],
},
serverMessages: {},
accessToken: false,
accessedUserPage: {
userData: {},
userPosts: {},
},
};
const AppProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const registerSubmitHandler = async (userInputs) => {
const registeredUser = await registerNewUser(userInputs);
dispatch({ type: "REGISTER_USER", payload: registeredUser.data });
};
const authUserCredentials = async (userCredentials) => {
const userDataFromDb = await authUser(userCredentials);
localStorage.setItem("access_token", userDataFromDb.token);
dispatch({
type: "AUTH_USER",
payload: userDataFromDb,
});
};
const getUserDataByToken = async (token) => {
const userDataFromDb = await validateUserToken(token);
dispatch({ type: "LOGGED_GET_DATA", payload: userDataFromDb });
};
const editUserAccount = async (token, accountData) => {
const editedUserData = await editAccountData(token, accountData);
dispatch({ type: "EDIT_USER_ACCOUNT", payload: editedUserData });
};
const getUserPostsData = async (token) => {
const postsDataFromDb = await getUserPosts(token);
dispatch({ type: "FETCH_USER_POSTS", payload: postsDataFromDb });
};
const getBuddyData = async (nicknameParam) => {
const userDataFromDb = await accessUserProfile(nicknameParam);
dispatch({ type: "ACCESS_FRIEND_PAGE", payload: userDataFromDb });
};
const userLogout = async () => {
await localStorage.removeItem("access_token");
const emptyState = {
...state,
userState: {
userData: "",
userPosts: "",
},
};
dispatch({ type: "USER_LOGOUT", payload: emptyState });
};
return (
<AppContext.Provider
value={{
...state,
registerSubmitHandler,
authUserCredentials,
getUserPostsData,
userLogout,
getBuddyData,
getUserDataByToken,
editUserAccount,
}}
>
{children}
</AppContext.Provider>
);
};
export const useGlobalContext = () => {
return useContext(AppContext);
};
export { AppProvider, AppContext };
2
Answers
in advance, I would like to thank you for all your help. I've noticed that in some components that I use material UI, it receives the "href" property, so, this was conflicting with my navigation along the pages, so I've removed the "href" links, and the application works properly, but I figured out things because you guys helped me! Thank you all, here's a little piece of my code:
I don’t see anything very odd with your code.
Nevertheless, it is a best practise to encapsulate your context value in a memo. If you don’t do that, all components which consume this context render more times than they need.
Could you try that please?