Reputation: 149
Let's say I have these routes:
<Switch>
<Route exact path="/myflix/:slug" component={Home} />
<Route exact path="/myflix/:slug/register" component={Signup} />
<Route exact path="/myflix/:slug/event" component={Event} />
<Route exact path="/myflix/:slug/contact" component={Contact} />
<Route exact path="/myflix/:slug/login" component={Login} />
<Route exact path="/myflix/:slug/show-details" component={ShowList} />
<Route exact path="/myflix/:slug/*" component={NotFound} />
<Route path="*" exact={true} component={NotFound} />
<Redirect to="/not-found" />
{/* <Route path="*" element={<NotFound />} /> */}
</Switch>
We have certain slugs from an API, in this form:
[
{
id: 1,
title: "_flix",
slug: "_flix",
status: true,
viewTime: null,
langue: null,
createdAt: "2021-06-24",
updatedAt: null,
},
{
id: 9,
title: "test_flix",
slug: "test_flix",
status: true,
viewTime: null,
langue: null,
createdAt: "2021-06-24",
updatedAt: null,
},
{
id: 10,
title: "flix_2",
slug: "flix_2",
status: true,
viewTime: null,
langue: null,
createdAt: "2021-06-24",
updatedAt: null,
},
]
When I make an invalid slug, I want to redirect to the NotFound
page:
useEffect(() => {
getSlug(slug)
.then((res) => {
const { id } = res.data;
document.title = res.data.title;
getSetting(id).then((result) => {
setStyle(result.data);
getLangue(id).then((res) => {
setlang(res.data.langue);
});
});
})
.catch((error) => (window.location.href = "/not-found"));
}, [slug]);
I used the above code (see the .catch
), but when I make an invalid slug, it redirects not found page and refreshes the page. I need to redirect without refreshing. Any solution?
Upvotes: 3
Views: 2211
Reputation: 45963
window.location.href
refreshes the page. Since you seem to be using React Router Dom v5
, you should be using useHistory to make redirections. Here is an overview of how you would use it (notice the comments):
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory(); // you call it at the top level of the component
function handleClick() {
history.push("/home"); // use it wherever you want
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
Not related to useHistory
or the redirection, but you could optimize slightly your routes setup:
<Switch>
<Route exact path="/myflix/:slug" component={Home} />
<Route exact path="/myflix/:slug/register" component={Signup} />
<Route exact path="/myflix/:slug/event" component={Event} />
<Route exact path="/myflix/:slug/contact" component={Contact} />
<Route exact path="/myflix/:slug/login" component={Login} />
<Route exact path="/myflix/:slug/show-details" component={ShowList} />
<Route exact path="/not-found" component={NotFound} />
<Redirect to="/not-found" />
</Switch>
For React Router Dom v6
, use useNavigate is to be used instead of useHistory.
Upvotes: 2
Reputation: 202874
Using window.location.href = "/not-found"
mutates the current location and reloads the page, i.e. it will remount the entire React app. Use an imperative redirect to the "/not-found"
route.
import { useHistory } from 'react-router-dom';
...
const history = useHistory();
...
useEffect(() => {
getSlug(slug)
.then((res) => {
const { id, title } = res.data;
document.title = title;
getSetting(id)
.then((result) => {
setStyle(result.data);
});
getLangue(id)
.then((res) => {
setLang(res.data.langue);
});
})
.catch((error) => {
history.replace("/not-found"); // REPLACE = redirect
});
}, [slug]);
Render a Route
on path="/not-found"
that can be redirected to.
<Switch>
<Route path="/myflix/:slug/register" component={Signup} />
<Route path="/myflix/:slug/event" component={Event} />
<Route path="/myflix/:slug/contact" component={Contact} />
<Route path="/myflix/:slug/login" component={Login} />
<Route path="/myflix/:slug/show-details" component={ShowList} />
<Redirect from="/myflix/:slug/*" to="/not-found" /> // <-- redirect unhandled paths
<Route path="/myflix/:slug" component={Home} />
<Route path="/not-found" component={NotFound} /> // <-- render NotFound component route
<Redirect to="/not-found" />
</Switch>
Upvotes: 0