36

I make a mobile application with Cordova. Use the react-router@2.0.0 + 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?

3 Answers 3

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.

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)
    – gre
    Jun 27, 2017 at 9:20
0

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) {
        ...
    }
}
0

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().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.