larrymyers / react-mini-router

A minimal URL router for React.js
MIT License
282 stars 38 forks source link

Invariant Violation when working with hash routes in isomorphic app #36

Closed Merri closed 9 years ago

Merri commented 9 years ago

I have an isomorphic React app and I'm using react-mini-router in an independent app that is meant for client side only rendering. The problem is that apparently react-mini-router isn't aware on server side that it is being used like this and thus it always renders the index page server side, thus leading to Invariant Violation because client renders different path.

My current solution to this problem is uglyish:

    getInitialState: function() {
        return { clientRenderingIsSafeNow: false }
    },

    componentDidMount: function() {
        this.setState({ clientRenderingIsSafeNow: true })
    },

    render: function() {
        // server side doesn't know our hash path so we render wrong stuff in client and get Invariant Violation
        // so we render empty div in both server and client until componentDidMount, which happens only in client
        if (!this.state.clientRenderingIsSafeNow) {
            return <div />
        }
        return this.renderCurrentRoute()
    },

Is there a better way?

larrymyers commented 9 years ago

Take a look at the example app, it does client/server rendering. Specifically look at the renderApp method in server.js: https://github.com/larrymyers/react-mini-router/blob/master/example/server.js

If you're going to do an isomorphic app you need to be able to bootstrap your root Component with the same data on the client and server dependent on the current path.

Merri commented 9 years ago

That isn't my use case; for now I can't access all the information server side. So I only have client side rendering in the part of the app I'm using react-mini-router in.

But now that I've thought about this I guess the above code is the only even remotely good solution to this problem. The only other way to fix this issue would be to explicitly tell react-mini-router that it is only needed on client side so that it would do the above kind of empty rendering automatically.