Keep react-router routed-components for all history states
Asked Answered
F

3

41

I make a mobile application with Cordova. Use the [email protected] + ReactCSSTransitionGroup to implement the "card deck" animation. I have a strict Routes tree without the possibility of circular links.

To improve performance and save the state of the previous route-components, I would like to keep the whole history of them with unmounting only on pop-state or replace-state.

How to do it?

Fatal answered 18/3, 2016 at 15:16 Comment(0)
S
1

Maybe you can take advantage of the onEnter and onChange callbacks when configure rootRoute.

In onEnter callback back you can record the initial route path. In onChange callback you can compare cur/next route path, check recorded path history, and record path. Therefor since you can check and compare route path every time route changes, you can stop any circular links.

About save all component's state, if you use redux, the whole app state can save in an object, the redux store.

If you want save component's state at that time before leave, you can dispatch a save component state action in componentWillUnmount, and recover state in componentWillMount.

Here is a snippet:

var rootRoute = {
    path: '/',
    onEnter: enter,
    onChange: change,
    component: MyApp,
    indexRoute: { component: Home },
    childRoutes: [
        LoginRoute,
        ...
        {path: 'home', component: Home},
        {
            path: '*',
            component: NotFound
        }
    ]
};

function enter (next) {
    // pathStore record all navigation history
    pathStore.record(next.location.pathname);
}
function change (cur, next, c) {
    // when hit cur path links in nav, pathname is same, key is different.
    if (cur.location.pathname !== next.location.pathname) {
        ...
    }
}
Shimmer answered 3/11, 2016 at 3:17 Comment(0)
S
1

Ionic provides this feature with their IonRouterOutlet component to allow transitions between pages. It's not quite trivial to follow the implementation but maybe you can take a look at their Repo.

What they are doing is basically wrap React's BrowserRouter and keep all routes rendered - toggling their visibility via css.

Note that this is not meant to improve performance but allow transitions. Rather than improving performance it might actually hinder it. For example to clean-up resources via useEffect cleanup functions or componentWillUnmount().

Sclater answered 5/12, 2021 at 18:19 Comment(0)
B
0

Are you sure this would actually help? If I get your point, you'd like to "cache" the components so that when you revisit an existing route, there's no need to recreate the DOM structure (I think Ionic has an option to do exactly that).

I'm not sure how much of a benefit you would get as React uses a virtual DOM implementation that should already update the DOM in an efficient way. When you transition from a route to another, only a minimum DOM nodes would be changed, according to the diff with the real DOM and your React representation.

If you want to "cache" the state of your components so you don't have to recalculate it every time, then it would be a lot easier to use something like redux and reselect (https://github.com/reactjs/reselect) to update the data you give your components only when needed, basically completing extracting the state out of your components. Your state would then survive the unmount of a component.

Reselect uses function memoization to recalculate the props you pass to your components only when it's needed, as opposed to every time something has changed.

Bathelda answered 11/5, 2016 at 13:3 Comment(1)
one usecase is to preserve the scrolled position and do a reversed transition to get back to previous exact state (there are many implicit hidden state, like input states, scroll position, etc.. that are not covered by React)Hippolytus

© 2022 - 2024 — McMap. All rights reserved.