You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First, I'll notice that since I'm not a native English speaker, there may be some awkward sentences that you may not understand well. If so, please let me posted :)
Currently, the animated-transition JSX template looks like this. (From example)
<TransitionGroup><CSSTransitionkey={location.key}classNames="fade"timeout={300}><Switchlocation={location}><Routeexactpath="/hsl/:h/:s/:l"component={HSL}/><Routeexactpath="/rgb/:r/:g/:b"component={RGB}/>{/* Without this `Route`, we would get errors during the initial transition from `/` to `/hsl/10/90/50` */}<Routerender={()=><div>Not Found</div>}/></Switch></CSSTransition></TransitionGroup>
After I tried to use this code, I found out that there is a big problem.
Problem
Nested route is useless when <Transition> is used
Since CSSTransition has location.key as key prop, whenever the path is changed, even subroute path changing, location.key value will be replaced with new value. This occurs CSSTransition and its descendants must be re-rendered with completely new DOM. This is a huge waste of performance. Besides, animation also occurs when subroute path is changed.
Example
Here is the basic behavior what I am going to propose.
As you can see, there is a first level route which are /A and /B with colored box component.
For each first level route, there's a nested second level route with HELLO! string, which is /{FIRST_ROUTE}/A
When first level route changes, the opacity of colored box will fade in or fade out.
When second level route changes, HELLO! string will wiped in or wiped out.
Finally, when first level route changes while second level route is activated, first level transition and second level transition will be fired simultaneously.
Proposal
To achieve this, some base logic should be changed.
First, for <Route> component, I propose a new prop which is always.
It always renders its component regardless of matching.
It is logically similar with children prop but some props passed to its component are different.
One of the problem of animated-transition is described below.
Transition occurs when URL is changed. Now let's assume RouteA should disappear.
RouteA, even though it is not matched anymore, should be rendered for some more 'animating' time.
Since props related with router (eg: match, location) are passed by its ancestor route, RouteA receives its props but it is not valid anymore. Particularly, match prop will be NULL. This may crashes the application if there's a code something like using match.url because match is undefined and raises error eventually.
To solve this problem, <Route> will remember its latest matchedmatch and location state. Now, even though <Route> is not matched anymore, <Route> knows its latest rendered state and its content can be rendered with it.
Now here's the difference between children prop and always prop. children prop receives match and location prop according to its current history state. always prop receives them according to its current history state when route is matched, if not, it receives them according to its latest matched state.(eg: when route is not matched) Additionally, there are additional props, rawMatch and rawLocation. They are based on current history state, just same with match and location props of children.
Now using always prop and <CSSTransition> component, implementing transition is fairly easy.
I'll make PR if you guys are interested. Please feel free to have a discussion with me !
There's another animating problem with Switch and Parameter Route but I will separately describe it later if this current topic can be discussed well with others.
The text was updated successfully, but these errors were encountered:
If you need to remember the previous state, you would do that from within a child component of Route. Route doesn't need to remember anything about the previous state; that's not its concern. You can compose in something that does retain state without affecting this library.
First, I'll notice that since I'm not a native English speaker, there may be some awkward sentences that you may not understand well. If so, please let me posted :)
Currently, the animated-transition JSX template looks like this. (From example)
After I tried to use this code, I found out that there is a big problem.
Problem
Nested route is useless when
<Transition>
is usedSince
CSSTransition
haslocation.key
as key prop, whenever the path is changed, even subroute path changing,location.key
value will be replaced with new value. This occursCSSTransition
and its descendants must be re-rendered with completely new DOM. This is a huge waste of performance. Besides, animation also occurs when subroute path is changed.Example
Here is the basic behavior what I am going to propose.
As you can see, there is a first level route which are
/A
and/B
with colored box component.For each first level route, there's a nested second level route with
HELLO!
string, which is/{FIRST_ROUTE}/A
When first level route changes, the opacity of colored box will fade in or fade out.
When second level route changes,
HELLO!
string will wiped in or wiped out.Finally, when first level route changes while second level route is activated, first level transition and second level transition will be fired simultaneously.
Proposal
To achieve this, some base logic should be changed.
First, for
<Route>
component, I propose a new prop which isalways
.It always renders its component regardless of matching.
It is logically similar with
children
prop but some props passed to its component are different.One of the problem of animated-transition is described below.
match
,location
) are passed by its ancestor route, RouteA receives its props but it is not valid anymore. Particularly,match
prop will beNULL
. This may crashes the application if there's a code something like usingmatch.url
becausematch
is undefined and raises error eventually.To solve this problem,
<Route>
will remember its latest matchedmatch
andlocation
state. Now, even though<Route>
is not matched anymore,<Route>
knows its latest rendered state and its content can be rendered with it.Now here's the difference between
children
prop andalways
prop.children
prop receivesmatch
andlocation
prop according to its current history state.always
prop receives them according to its current history state when route is matched, if not, it receives them according to its latest matched state.(eg: when route is not matched) Additionally, there are additional props,rawMatch
andrawLocation
. They are based on current history state, just same withmatch
andlocation
props ofchildren
.Now using
always
prop and<CSSTransition>
component, implementing transition is fairly easy.By nesting them, nested-level transition can also be implemented.
Of course it can be combined with HOC if needed.
I'll make PR if you guys are interested. Please feel free to have a discussion with me !
There's another animating problem with
Switch
andParameter Route
but I will separately describe it later if this current topic can be discussed well with others.The text was updated successfully, but these errors were encountered: