6

In my render function I have

<Route path="/classes/:course" render={(match) => (
   <Redirect to={`/classes/${match.params.course}/home`} />
)}>
   <Route path="/home" component={Home} />
</Route>

For example if the param for "course" was "BIO1001", I want to redirect the page to "/classes/BIO1001/home" when I go to the page "/classes/BIO1001/". Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"

Also would the nested route with path="/home" go to "/classes/BIO1001/home"? I was unsure on how I can set a route where the path starts from the previous url (in this case starting from "/classes/:course/"

3 Answers 3

4

The first problem is right here:

render={(match) => ( ...

The render function gets a props object which contains a match property. Instead of destructuring the match property, what you are actually doing is assigning the whole props object to a variable match. So when you go to access match.params it won't be found.

You need curly braces around match in order to destructure it.

render={({match}) => ( ...

The second problem is the nesting of the two Route components. I get a warning:

Warning: You should not use <Route render> and <Route children> in the same route; <Route render> will be ignored

So based on that warning you can see that your Redirect is being entirely ignored since it comes from render. The child Route is seen as the render function for the classes Route.

I'm assuming you have various subpages of a course? And we want to force the URL to include "/home" if none is set? (Personally I would do the opposite and redirect "/home" to the course root URL).

Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"

Per the docs, you can use params in your Redirect, but only if it is inside a Switch.

Here's a sample code to do that:

const CoursePage = () => {
  // you can access arguments from the props or through hooks
  const { course, tab } = useParams();

  // not sure how you want to handle the different tabs

  return <div>Viewing Course {course}</div>;
};

const App = () => (
  <BrowserRouter>
    <Switch>
      <Route path="/classes/:course/:tab"><CoursePage/></Route>
      <Redirect from="/classes/:course" to="/classes/:course/home"/>
    </Switch>
  </BrowserRouter>
);

export default App;
Sign up to request clarification or add additional context in comments.

2 Comments

This code still goes to the url with the params ":course" instead of the actual course params. i.e. If I enter localhost:3000/classes/BIO1001, it redirects to localhost:3000/classes/:course/home.
Maybe this is obvious to others, but the Redirect component with from and to will actually only work as a child of Switch. That means even a fractional component (<></>) will cause params to be lost.
1

Your nested routing is true i think. But you are rendering your Home component without any dynamic props. Try it like below:

<Route path="/classes/:course" render={(match) => (
   <Redirect to={`/classes/${match.params.course}/home`} />
)}>
   <Route path="/home" >
      <Home someProps={someValue} />
   </Route>
</Route>

1 Comment

add sample code in codesandbox for testing
0

Note: The Redirect element can be used without a containing Route element by providing a from property. In this case, you can just use the URL parameter tokens in both from and to, and they'll be carried over for you. For example, if you're using a Switch block...

<Switch>
  {/* various app routes... */}

  {/* redirect action */}
  <Redirect from="/classes/:course" to="/classes/:course/home" />
<Switch>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.