DrMister DrMister - 2 months ago 15
React JSX Question

How to temporarily handle routing when migrating a rails app to react?

I'm getting ready to migrate a monolithic rails app to a react app with a rails backend and json api. For now we've integrated the react application as a static asset in our rails app, and are slowly transitioning every page to be rendered by react.

Problem is, that the react app doesn't do the routing (because the rails app handles it currently). Only when all pages have been transferred do we want to transition the frontend completely to react.

However, the react app shouldn't render the same content on every page of course. It should render the appropriate content, based on the page on which it is initiated (and it would reinitiate for every pageload, but the script for the app itself would remain the same).

So the question is, what would be the recommended way to enable react to render the appropriate content. Does it make sense to use react-router, and use it only to render the content based on the url, but not have it handle links?

Answer

So in your route file:

export default function(requirePlanData) {
    return (
        <Route path="/">
            <Route path="(:lang/)reading-plans" component={PlansView}>
            <Route path=":id(-:slug)" component={AboutPlanView} onEnter={requirePlanData} />
        </Route>

    )
}

Here you can see that on render of '/en/reading-plans/903' the 'AboutPlanView' component will be rendered, and the 'requirePlanData' function will be called to populate the app state required for the component view.

In your main js file with your requirePlanData you can do call your action creators for your API calls and populate state with your reducers before the view is loaded:

function requirePlanData(nextState, replace, callback) {
    const { params } = nextState
    var idNum = parseInt(params.id.toString().split("-")[0])
    const currentState = store.getState()
    if (currentState && currentState.plansDiscovery && currentState.plansDiscovery.plans && currentState.plansDiscovery.plans.id === idNum) {
        callback()
    } else if (idNum > 0) {
        store.dispatch(PlanDiscoveryActionCreators.readingplanInfo({ id: idNum, language_tag: window.__LOCALE__.planLocale }, store.getState().auth.isLoggedIn)).then((event) => {
           callback()
        }, (error) => {
           callback()
        })
    } else {
        callback()
    }
}

Now your action creators will return, fire off your reducer to populate state, and your component will be able to render with all the required data–based off of the url/route you defined.

Does this help you?