- Understand the use cases for programmatic navigation
- Use the
useHistory
hook to perform programmatic navigation - Use the
<Redirect>
component to perform programmatic navigation
So far, we've used a couple components from React Router to allow our users to
navigate our React site: the NavLink
and Link
components. However, it would
also be useful to direct our users to another page without them needing to
click a link. For example:
- After logging in to the website, direct our user to the home page
- After logging out of the website, direct our user to the login page
- After creating a new item by filling out a form, direct our user to the detail page for that item
All of these actions require us to use programmatic navigation to change the browser URL, and show the user a new page in our application, without making the user click on a link.
To solve this problem, we can use another custom hook from React Router: the
useHistory
hook. Here's how it looks:
import { useHistory } from "react-router-dom";
function NavBar({ onLogout }) {
const history = useHistory();
function handleClick() {
// logout the user
onLogout();
// then navigate them to the login page
history.push("/login");
}
return (
<nav>
<button onClick={handleClick}>Logout</button>
</nav>
);
}
By calling history.push()
, we can effectively navigate the user to a new page
in response to any event in our application, not just when the user clicks a
link!
For another example, here's how you could use history.push()
to redirect the
user after logging in:
function Login({ onLogin }) {
const [formData, setFormData] = useState({
username: "",
password: "",
});
function handleChange(e) {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
}
function handleSubmit(e) {
e.preventDefault();
fetch("http://localhost:3001/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
})
.then((r) => r.json())
.then((user) => {
onLogin(user);
// after logging the user in, redirect to the home page!
history.push("/home");
});
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
/>
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
<button type="submit">Login</button>
</form>
);
}
In addition to the useHistory
hook, React Router also provides a special
component for redirecting users to a new location: the Redirect
component.
This component is particularly useful in cases where you need to handle some
conditional rendering. For example:
function Home({ isSignedIn }) {
// if the user isn't signed in, redirect them to the login page
if (!isSignedIn) return <Redirect to="/login" />;
// otherwise, return the home page
return (
<div>
<h1>Home!</h1>
</div>
);
}
React Router gives us full control over how to navigate users around our
website. In general, the preferred approach is to use the <Link>
and
<NavLink>
components to let users perform navigation by clicking links.
However, there are certain scenarios when we want to navigate a user to a new
page after they perform some other type of action, like submitting a form or
logging out. React Router provides two tools to help us with these scenarios:
the useHistory
hook and the <Redirect>
component.