React-router: V6: Optional parameters

Created on 27 Apr 2020  Â·  10Comments  Â·  Source: ReactTraining/react-router

I tried adding a trailing ? to a route using the v6 router, but it didn't seem to work.

<Route path='/page/:friendlyName/:sort?' element={<Page/>} />

Are optional parameters supported in v6, or are they coming later?

All 10 comments

We don't plan on supporting them in v6.

@timdorr Thanks - could you explain a little on how you would achieve it in v6? At the moment I have the below which works but seems less than optimal. Any thoughts?

<Route path='/page/:friendlyName/:sort' element={<Page/>} />
<Route path='/page/:friendlyName/' element={<Page/>} />

It would be great if this could be described in the migration guide – or if there was at least a hint. So the recommended way of doing "optional" params really is ...

<Route path='/page/:friendlyName/:sort' element={<Page/>} />
<Route path='/page/:friendlyName/' element={<Page/>} />

... ?

@gopeter Yes, or you can do something like this:

<Route path="/page/:friendlyName">
  <Route path=":sort" element={<Page />} />
  <Route path="" element={<Page />} />
</Route>

Aaaaah, great, thank you very much! 😄

@MeiKatz @timdorr my problem with the approach above is that the <Page> component unmounts and mounts again. Performance-wise this might be a bad thing, but in my case it also results in a bunch of refetching of data. I can fix this inside the Page-component itself by checking if data is there already, but not only does this change break my routing, it also breaks application itself.

This is my use case;

<Route path="tickets">
  <Routes>
    <Route path="archive">
      <Route path=":ticketId/:content" element={<List />} />
      <Route path=":ticketId" element={<List />} />
      <Route path="/" element={<List />} />
    </Route>
    <Route path="view/:ticketId">
      <Route path=":content" element={<List />} />
      <Route path="/" element={<List />} />
    </Route>
    <Route path=":ticketId">
      <Route path=":content" element={<List />} />
      <Route path="/" element={<List />} />
    </Route>
    <Route path="/" element={<List />} />
  </Routes>
</Route>

A user starts at /tickets, then clicks on a link on the list that navigates to /tickets/1. This now re-renders the complete page where before it would re-render a part inside the component. Navigating from /tickets/1 to /tickets/2 works as expected.

Any other suggestions on how to implement this (Route-wise) without having to refactor the complete <List/>-component?

@robbinjanssen Have you thought about using the <Outlet /> element?

<Route path="tickets" element={ <TicketsPage /> }>
  <Route path=":ticketId" element={ <ShowPage /> } />
  <Route path="" element={ <IndexPage /> } />
</Route>
const TicketContext = React.createContext( {} );

function TicketsPage() {
  const [ tickets, setTickets ] = useState({});

  useEffect(() => {
    // do some loading stuff
    const res = await fetch("/tickets");
    const tickets = await res.json();

    setTickets( tickets );
  }, []);

  return (
    <Fragment>
      <h1>My Tickets</h1>
      <TicketContext.Provider value={ tickets }>
        <Outlet />
      </TicketContext.Provider>
    </Fragment>
  );
}

function ShowPage() {
  const tickets = useContext( TicketContext );
  const { ticketId } = useParams();

  const ticket = tickets[ ticketId ];

  return (
    <div>{ JSON.stringify( ticket ) }</div>
  );
}

@MeiKatz not yet, hoped I would not have to refactor that ticket page, but seems like there's no other way. It's a pretty "old" component that requires a lot of work when refactoring. So I wish I could somehow keep the optional parameters :)

@robbinjanssen Understandable. But I don't think that there is any other way you can solve it. And I also think, that it is a clean way to do it. Also we could think about dropping the whole context stuff and pass the parameters to the <Outlet /> and from there to the element.

For now I'll just parse the "raw" params into the bits I need, those URLs are not that complicated fortunately, and i'll put the component on the refactor list. Thanks :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stnwk picture stnwk  Â·  3Comments

hgezim picture hgezim  Â·  3Comments

davetgreen picture davetgreen  Â·  3Comments

alexyaseen picture alexyaseen  Â·  3Comments

jzimmek picture jzimmek  Â·  3Comments