2

I wrote the Routes in my project as below:

<Routes>
  <Route exact path="/" element={<Home />} />
  <Route exact path='/login' element={<Login />} /> 
  <Route exact path='/about' element={<About />} />
  <Route exact path='/store' element={<Store />} />
  <Route exact path='/store/:productID' element={<Product />} />
  <Route path={['/not-found', '*']} element={<NotFound />} /> 
</Routes>

In Product page I want to display the existing product ids and redirect the other ones to not-found page:

{!check && navigate("/not-found", {replace: true})}
<div className="container">
  <ul>
    <li>Product ID: {productID}</li>
    <li>Name: {check.name}</li>
    <li>Price: {check.price}</li>
    <li><img src={check.image} /></li>
  </ul>
</div>

but I'm getting this error: Uncaught TypeError: meta.relativePath.startsWith is not a function

I also wrote it with navigate component:

{!check && <Navigate to="/not-found" />}

Still displays a white page for not existing ids.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Jupixel
  • 53
  • 7
  • You can follow this post : [Link](https://stackoverflow.com/questions/40933619/how-to-redirect-to-a-certain-route-based-on-condition-in-angular-2) Hope this will help you. – Gurpreet Singh Mar 01 '23 at 07:59

3 Answers3

2

The Route component's path prop takes only a string value, not an array. You'll need to split the two route paths up. I suggest rendering the NotFound component on path="/not-found" and redirect all unhandled/unknown paths to it.

Example:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/login" element={<Login />} /> 
  <Route path="/about" element={<About />} />
  <Route path="/store" element={<Store />} />
  <Route path="/store/:productID" element={<Product />} />
  <Route path="/not-found" element={<NotFound />} />
  <Route path="*" element={<Navigate to="/not-found" replace />} />
</Routes>

The product page should also render the Navigate component if you are trying to apply the redirect logic in the render return.

{check
  ? (
    <div className="container">
      <ul>
        <li>Product ID: {productID}</li>
        <li>Name: {check.name}</li>
        <li>Price: {check.price}</li>
        <li><img src={check.image} /></li>
      </ul>
    </div>
  )
  : <Navigate to="/not-found" replace />
}

Otherwise the navigate function should only be called in a callback or useEffect hook.

useEffect(() => {
  if (!check) {
    navigate("/not-found", { replace: true });
  }
}, [check]);

...

if (!check) {
  return null;
}

return (
  ...
  <div className="container">
    <ul>
      <li>Product ID: {productID}</li>
      <li>Name: {check.name}</li>
      <li>Price: {check.price}</li>
      <li><img src={check.image} /></li>
    </ul>
  </div>
  ...
);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
0

The 404 page displays for paths that don’t exist on the website. So, instead of specifying the path, use an asterisk (*).

You can make NotFound component like this:

import { Link } from "react-router-dom";

export default function NotFound() {
    return (
        <div className="container">
            <ul>
                <li>Product ID:</li>
                <li>Name:</li>
                <li>Price:</li>
                <li><img src={""} /></li>
            </ul>
        </div>
    )
}

And You can add Route for NotFound component on main component.

<Route path='*' element={<NotFound />}/>

Using * renders the NotFound component for all the URLs not specified in routes.

0

Use a seperate route for /not-found and redirect all none-existing path to it.

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/login" element={<Login />} /> 
  <Route path="/about" element={<About />} />
  <Route path="/store" element={<Store />} />
  <Route path="/store/:productID" element={<Product />} />
  <Route path="/not-found" element={<NotFound />} />
  <Route path="*" element={<Navigate to="/not-found" replace />} />
</Routes>

And use the Navigate componenet.

if (check) {

    <div className="container">
      <ul>
        <li>Product ID: {productID}</li>
        <li>Name: {check.name}</li>
        <li>Price: {check.price}</li>
        <li><img src={check.image} /></li>
      </ul>
    </div>

}

return <Navigate to="/not-found" replace />

Depending on how you determine if ids exist, you can use redirect() too. In fact, react-rouer recommends using redirect instead of useNavigate()

It's usually better to use redirect in loaders and actions than this hook

https://reactrouter.com/en/main/hooks/use-navigate

mahan
  • 12,366
  • 5
  • 48
  • 83