ctrlplusb / react-async-component

Resolve components asynchronously, with support for code splitting and advanced server side rendering use cases.
MIT License
1.45k stars 62 forks source link

Document the "multiple componentWillMount" behaviour #22

Open bradbarrow opened 7 years ago

bradbarrow commented 7 years ago

Hey, thanks for your work on this.

I use componentWillMount to kick off some redux-thunks that do data fetching for my component on the server side.

Since react-async-component walks the tree to find the async components, it triggers all of the componentWillMount calls...then I still have to render the resulting appWithAsyncComponents with react-dom that invokes all of those componentWillMounts again.

The result is that I end up hitting my API twice for everything...once while finding the async components, and once when actually rendering to string.

UPDATE: I also find when using react-resolver that the same occurs. Essentially, any data fetching / expensive activity that's triggered by a pass over the tree would have to happen twice with this sort of approach.

ctrlplusb commented 7 years ago

Yeah, a difficult one to manage. Ideally I would love to be able to skip the componentWillMount call completely, but it's a part of the React server side contract and lots of people set up critical state within this lifecycle method for the render. We need this state to render and walk the tree correctly.

I have another library react-jobs which also makes use of the tree walking technique. I plan to create an integration layer so that the use of both does not result in a double tree walk. I can and do fire redux-thunk based actions in my own implementations using react-jobs. It's a bit more boilerplate but you can create util functions to cover your own use case.

Sorry, not looking for self promotion, but it's the only solution I know of thus far if you are wanting to do full server side rendering.

Full server side rendering is a pain. If SEO isn't absolutely critical to you my recommended approach is to use async components with the ssrMode: 'defer' option set. Render your app shell on the server for perceived performance, have everything else render client side. This doesn't fit everyones case of course, which I can appreciate. However I'd like to reiterate this as I often hear of people trying do SSR react without considering what parts of their app need to be SSR'ed and what other parts could be deferred. Code splitting is still a massive win.

gabemeola commented 6 years ago

Could you use asyncBootstrap() from react-async-bootstrapper https://github.com/ctrlplusb/react-async-bootstrapper#naive-example ? Shouldn't this only be called once?