Hi, folks. I’m running into an issue with React Router’s Redirect component, and I was wondering if I could get another pair of eyes on it to find out what’s going wrong. It always redirects to '/'
instead of the path
that I have in the to
object. Here’s the code. The Redirect is in the conditional return statements at the bottom.
import React, { useState, useEffect } from "react";
import { Redirect } from "react-router-dom";
function Private(props) {
let [user, updateUser] = useState({});
let [loggedOut, setLoggedOut] = useState(false);
useEffect(() => {
getUser();
}, []);
let flashSuccess;
try {
flashSuccess = props.location.state.flashSuccess;
} catch {}
const getUser = () => {
fetch("/api/getUserInfo")
.then(res => res.json())
.then(json => {
updateUser(json);
});
};
const logout = () => {
fetch("/api/logout").then(() => {
window.localStorage.removeItem("qrs");
setLoggedOut(true);
});
};
// REDIRECT HERE ************************************************
if (loggedOut) {
return (
<Redirect
to={{
path: "/login",
state: { flashInfo: "Please log in to continue." }
}}
/>
);
} else {
return (
<div className="App">
{flashSuccess ? (
<div className="alert alert-success">{flashSuccess}</div>
) : null}
<h1>IT WORKS!!!</h1>
<h1>{JSON.stringify(user)}</h1>
<button className="btn btn-primary" onClick={logout}>
Log Out
</button>
</div>
);
}
}
export default Private;
I’m using the exact same technique in another component, and it works just fine there. That code, for comparison:
import React, { useState } from "react";
import { Redirect } from "react-router-dom";
function Login(props) {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [redirect, setRedirect] = useState({
redirect: false,
path: "",
msg: ""
});
const [flashError, setFlashError] = useState("");
let flashSuccess;
try {
flashSuccess = props.location.state.flashSuccess;
} catch {}
let flashInfo;
try {
flashInfo = props.location.state.flashInfo;
} catch {}
const handleSubmit = async e => {
e.preventDefault();
let options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: username, password: password })
};
fetch("/api/login", options)
.then(response => response.json())
.then(json => {
setUsername("");
setPassword("");
if (json.error) {
props.location.state.flashSuccess = "";
setFlashError(json.error);
} else if (json.user) {
window.localStorage.setItem("qrs", json.user);
setRedirect({
redirect: true,
path: "/private",
msg: "Login successful!"
});
}
});
};
// REDIRECT HERE *********************************************
if (redirect.redirect) {
return (
<Redirect
to={{
pathname: redirect.path,
state: { flashSuccess: redirect.msg }
}}
/>
);
} else {
return (
<div>
<h1>Login</h1>
{flashSuccess ? (
<div className="alert alert-success">{flashSuccess}</div>
) : flashError ? (
<div className="alert alert-danger">{flashError}</div>
) : flashInfo ? (
<div className="alert alert-info">{flashInfo}</div>
) : null}
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Username</label>
<input
type="username"
className="form-control"
id="exampleInputEmail1"
onChange={e => setUsername(e.target.value)}
value={username}
autoFocus
/>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
onChange={e => setPassword(e.target.value)}
value={password}
/>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
</div>
);
}
}
export default Login;
Again, it’s in the conditional return statements at the bottom.
Thanks for taking a look!