brocoders / redux-async-connect

It allows you to request async data, store them in redux state and connect them to your react component.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Initial rendering works fine on the server, but returns `<noscript>` in browser.

denisftw opened this issue · comments

commented

I'm building a universal React app with Redux and ReactRouter.

I needed to load some data asynchronously from the server and was advised to use your library. It mostly works fine, but for some reason the initial browser rendering returns the empty noscript tag, so I'm seeing the following in the browser:

Instead, figure out why the markup being generated is different on the client or server:
(client) <noscript data-reacti
(server) <div class="admin-hom

Interestingly, after that the page loads, props are initialized and everything works as expected including replacing views without reloading the page etc. I was wondering what could be the cause of this. I'm using the same logic for loading data in browser as I do on the server and my browser-side routing part is essentially this:

window.onload = function() {
    const store = createStore(combineReducers({reduxAsyncConnect}));
    ReactDOM.render(
        <Provider store={store} >
            <Router history={browserHistory} 
                render={(props) => <ReduxAsyncConnect {...props} />} >
                <Route path='/' component={ViewComposite} />
                <Route path='/profile/:urlCode' component={ProfileComposite} />
                <Route path='/admin' component={AdminComposite}  />
            </Router>
        </Provider>,
        document.getElementById('viewMount')
    );
}

In the component file, I'm loading data using Axios:

const mapStateToProps = {
    data: (params, helpers) => {
        const url = 'http://localhost:9000/api/data/view';
        const request = axios.get(url);
        return request.then(function (response) {
            return response.data;
        })
    }
};

class ViewComposite extends React.Component {
 //...
}

export default asyncConnect(mapStateToProps)(ViewComposite);

If I understand correctly, the fact that we're returning a promise should have postponed the rendering in the browser until data is here. Is it possible to get more insight into what's going on behind the scenes and why it behaves differently?

Edited - Removed irrelevant details.

I ran into this a few weeks ago getting going with redux-async on universal, but I forget what the solution was exactly. It was not an issue with redux-async. I remember logging out to the node console window the rendertostring of and then googled for what it said. It was a unrelated stack overflow or github issue that at least gave a clue on how to proceed.

commented

I encountered the same issue on the server using the latest version of redux-async-connect (1.0.0-rc4), downgrading to 1.0.0-rc2 solved this discrepancy for me. Later I did encounter <noscript> being rendered on the client on one occasion - but in a completely different setup, so I'm afraid I can't provide any further pointers there.

One thing I do notice from the snippet is that you're not injecting your server data into createStore.

commented

Yeah, I used to inject the data in the onEnter callbacks, but then I found that it isn't necessary. Initially, I also had a noscript issue on server, because I didn't use loadOnServer. Now it's good on server, but I still have noscript on client.

I'm using version "0.1.13", though. Maybe I should give "1.0.0-rc2" a try.

FYI, I also had an empty <noscript> markup in the server render, until I downgraded to 1.0.0-rc2

btw thank for the workaround ;)