2

My shallow understanding is causing a simple issue with rendering the NotFound page...

<Routes>
          <Route path="*" element={<NotFound />}/>
          <Route path="/" element={<Home />} />
          <Route path="/:category/:id" element={<Article />} />
        </Routes>

When the uri contains one "/", it renders the matching component or NotFound component, however, when the uri includes two "/", for example "/asoejdnxx/acnoiw" which doesn't exist, it doesn't route to the NotFound page but just renders a blank page with no errors.

I'm assuming the issue is because react is looking for the params in the thirds Route(which has the :category and :id param) regardless of it matching or not.

I'm sure there should be no need to add a condition in the "Article" component, such as if the param doesn't match to an existing :id, render something else(since thats the purpose of path="*"), but i cant find a way to redirect or render the NotFound component.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
moon
  • 23
  • 1
  • 8
  • What makes you think that `"/asoejdnxx/acnoiw"` wouldn't be matched by `path="/:category/:id"` and render the "404" route and `NotFound` component? – Drew Reese Jun 29 '22 at 05:25
  • Does this answer your question? [How to build a 404 page with react-router-dom v6](https://stackoverflow.com/questions/67050966/how-to-build-a-404-page-with-react-router-dom-v6) – Jay Jun 29 '22 at 05:26
  • @DrewReese I may be using the incorrect terminology but the "asoejdnxx" and "acnoiw" params don't exist. they're both made up strings that don't match any params – moon Jun 29 '22 at 05:29
  • Right, and how would the route component know what are valid strings? It takes a URL path and parses it and finds a matching path string. In any case, the routed component still needs to handle validating the params it receives. I've provided an answer below with example. – Drew Reese Jun 29 '22 at 05:32

2 Answers2

4

What makes you think that "/asoejdnxx/acnoiw" wouldn't be matched by path="/:category/:id" and render the "404" route and NotFound component instead?

For URL path "/asoejdnxx/acnoiw" the path="/:category/:id" will match it and render the Article component. It's at this point that Article needs to validate the route params it's consuming and if they are invalid, redirect to the 404 route.

I suggest actually creating a 404 route that you can redirect to.

Example:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/:category/:id" element={<Article />} />
  <Route path="notfound" element={<NotFound />} />
  <Route path="*" element={<Navigate to="/notfound" replace />} />
</Routes>

In the Article component use a useEffect hook to redirect to "/notfound" under the correct circumstances.

Example:

const { category, id } = useParams();
const navigate = useNavigate();

...

useEffect(() => {
  if (/* invalid route params */) {
    navigate("/notfound", { replace: true });
  }
}, [category, id, navigate]);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thanks Drew i now understand how it works. i initially thought path="*" without any circumstances would do the work. – moon Jun 29 '22 at 05:37
  • hey Drew hate to bother you but how can i validate my params? ```js const {category, id} = useParams(); console.log(!category) console.log(!id) ``` i'm sure i shouldn't be taking an approach like that. Both params are strings FYI – moon Jun 29 '22 at 12:47
  • got it working using Object.keys() . – moon Jun 29 '22 at 13:18
1

You can manually redirect the user to the 404 page:

import { useNavigate } from "react-router-dom";
const YourComponent = () => {
    const navigate = useNavigate();
    if(/*some condition*/){
        navigate("/404");
    }
    return /*...*/
}```
Code Fingers
  • 293
  • 3
  • 21