Closed pshrmn closed 7 years ago
Is this a true statement: These problems exist only when passing a relative path?
This problem exists if you need to use the parent match
to build the URL, but it is null
. That can either be through built-in resolving or manually concatenating a path with match.url
. I'm not sure if you consider the latter case to be passing a relative path.
I have been thinking a lot about https://github.com/ReactTraining/react-router/pull/4539#discussion_r101928586 and what the correct behavior for resolving when
match === null
should be. This is only an issue with thechildren
prop when the<Route>
also has apath
prop. When we usecomponent
,render
, or there is nopath
, there is always* a parentmatch
to resolve with.This isn't exclusive to #4539 and #4459. The problem also exists with users who are manually "resolving" using string concatenation.
My conclusion is that relative paths inside of a
<Route path={path} children>
should be considered unsupported. Whenmatch
isnull
, we just do not have the necessary information to resolve a path.*Right now, there is not a root
match
object, so this statement isn't technically true. However, one could fairly trivially be added. As it standscontext.router.match
isundefined
, notnull
.matchPath
could differentiate between anundefined
and anull
parentMatch
, but the tendency to usecondition == null
throughout this project makes me think that having a rootmatch
is preferable.Below I have outlined a number of possible attempts at resolving when
match = null
and why they do not work.Case 0: A Match A control example. When the
<Route>
with achildren
prop matches, resolving will work as expected.Case 1: No Match One solution (which I had been using, but now realize is wrong) would be to resolve using the root (
/
) whenmatch
isnull
. This results in an incorrect path with automatic resolving andTypeError
s with manual resolving.Case 2: Parent Match Another approach would be to inherit the parent
match
. This approach would require adding an extra property tomatch
that indicates that it isn't a "real" match (match.matches = false
). It gets rid of theTypeError
s, but still results in incorrect URLs.Case 3: Join with Parent Match The above could be expanded on by joining the
path
of the route being matched with its parent match'surl
andpath
. This will not work because the route'spath
might include parameters. That is acceptable for resolving<Route>
path
s, but fails when resolving anything that expects an actual URL.Working Solution As I stated above, this is an information problem. When
match = null
, we cannot properly resolve a path. In this situation, the only way to guarantee that you get the correct URL is to use absolute paths.Generally speaking, I don't think that
<Route path={path} children>
will be used that often, especially for actual path matching. The one situation that comes to mind is "active" matching, like with the<NavLink>
. In that situation, the location should be resolved prior to passing it to the<Route>
because alocation.pathname
supports more complex relative paths thanpath
does (<Link to='..'>Parent</Link>
is valid,<Route path='..'>
is not).