Advertisements
I want to load different components on component mount based on the URL params but my useParams()
object room
is showing as undefined in my useEffect()
for some reason.
// App.js
function App() {
const { room } = useParams();
const [inGame, setInGame] = useState(false);
useEffect(() => {
console.log(room); // undefined
socket.emit("am_i_in_game", room, (res) => {
setInGame(res.inGame);
return;
});
return;
}, [room]);
return (
<ThemeProvider theme={darkTheme}>
<Routes>
<Route
path="/:room"
element={
inGame ? <GameScreen {...gameScreenProps} />
: room?.length === 6 ? (
<StartScreen {...{
...startScreenProps,
hasJoinEmbed: true
}} />
) : <StartScreen {...startScreenProps} />
}
/>
</Routes>
</ThemeProvider>
);
>Solution :
The App
component can’t read a route path parameter from a route rendered below itself.
I suggest creating a Room
component that is rendered on path="/:room"
and can read the room
route path parameter and issue the side-effect and render the appropriate content. Basically move the state and logic in App
down the ReactTree.
Example:
const Room = () => {
const { room } = useParams();
const [inGame, setInGame] = useState(false);
useEffect(() => {
console.log(room);
socket.emit("am_i_in_game", room, (res) => {
setInGame(res.inGame);
return;
});
}, [room]);
return inGame
? <GameScreen {...gameScreenProps} />
: (
<StartScreen
{...startScreenProps}
hasJoinEmbed={room?.length === 6}
/>
);
};
function App() {
return (
<ThemeProvider theme={darkTheme}>
<Routes>
<Route path="/:room" element={<Room />} />
</Routes>
</ThemeProvider>
);
}