I am building a web app using Meteor.js with React. The app has two types of users: "user" and "employer", each with their own routes (like different dashboards and other pages). So I have a UserRouter, an EmployerRouter, and an UnprotectedRouter (for when the user is not logged in yet). I want to return a different router depending on which user is logged in (I have a "type" field to let me know which user type they are). The issue is that the router is not updating when a user logs in. Basically I need different routers depending not only on if the user is logged in or not, but what TYPE of user it is.
I tried to do useState, but it wouldn’t update the router. Then I thought because the browser reroutes after the user signs up, maybe it would rerun App.tsx which would update the router to the correct one, but that did not work either. Right now when I start up the app, it renders the UnprotectedRouter because I’m not logged in. Then when I go to the sign-up form and create a new user (which logs me in automatically), it still shows UnprotectedRouter rather than UserRouter.
This is what my code currently looks like:
UserRouter.tsx
export const UserRouter = () => {
return (
<Routes>
<Route path={RoutePaths.USER_HOME} element={<UserHome />} />
<Route path={RoutePaths.USER_PROFILE} element={<UserProfile />} />
<Route path={RoutePaths.EMPLOYER_HOME} element={<EmployerHome />} />
<Route path={RoutePaths.USER_SIGNUP} element={<UserSignUp />} />
<Route path={RoutePaths.EMPLOYER_SIGNUP} element={<EmployerSignUp />} />
<Route path={RoutePaths.USER_SIGNIN} element={<UserSignIn />} />
<Route path="/position/:postingId" element={<UserPosting />}/>
</Routes>
);
};
EmployerRouter.tsx
export const EmployerRouter = () => {
return (
<Routes>
<Route path={RoutePaths.USER_HOME} element={<EmployerDashboard />} />
</Routes>
);
};
UnprotectedRouter.tsx
export const UnprotectedRouter = () => {
return (
<Routes>
<Route path={RoutePaths.WELCOME_PAGE} element={<WelcomePage />} />
<Route path={RoutePaths.USER_SIGNUP} element={<UserSignUp />} />
<Route path={RoutePaths.EMPLOYER_SIGNUP} element={<EmployerSignUp />} />
</Routes>
);
};
App.tsx
const selectRouter = (userType: String) => {
switch (userType) {
case "user":
return <UserRouter/>
case "employer":
return <EmployerRouter/>
default:
return <UnprotectedRouter/>
}
}
const RouterChoice = () => {
const isLoadingProfiles = useSubscribe("allUserProfiles");
const loggedInUsername = Meteor.user()?.username;
const userType = UserCollection.findOne({ username: loggedInUsername })?.type;
return selectRouter(userType)
}
export const App = () => {
const router = RouterChoice();
return (
<BrowserRouter>
<div>
{router}
</div>
</BrowserRouter>
)
};
This is what my sign-up method for users looks like:
const handleSignUp = (e: { preventDefault: () => void }) => {
e.preventDefault();
console.log("password is: " + password);
console.log("username is: " + username);
console.log("email is: " + email);
Accounts.createUser(
{
username: username,
password: password,
email: email,
},
(error) => {
if (error) {
console.log(error);
return;
} else {
console.log("success!");
}
}
);
Meteor.call("user-profile.createNewProfile", {
username: username,
name: name,
type: "user",
});
setName("");
setUsername("");
setEmail("");
setPassword("");
console.log("submitted!");
navigate(RoutePaths.USER_HOME);
};
Thank you for your help.
2
Answers
What I have rendered is on App.tsx you need to wrap
By a
Like this:
For the dependency I used <<Meteor.user()?.username>> but you should use what changes when the user logs in with a different account.
The issue it seems is that you have incorrectly cased the
RouterChoice
function name which "tricks" React, or rather "Rules of Hooks", into thinking thatRouterChoice
is a React component instead of a regular callback function.RouterChoice
calls auseSubscribe
React hook, but becauseApp
isn’t triggered to rerender it doesn’t call theuseSubscribe
again becauseRouterChoice
is never "called" again as a React component.Rename
RouterChoice
to something likeuseRouterChoice
so it’s called validly as a custom React hook.