sekoyo / universal-react

A universal react starter, with routing, meta, title, and data features
242 stars 50 forks source link

componentDidMount & duplicate data ... #24

Closed bresson closed 8 years ago

bresson commented 8 years ago

Really nice starter. How do you recommend checking if the async request on componentDidMount is duplicative of what the server rendered?

sekoyo commented 8 years ago

Thanks, I recommend doing it in your action - as you can see here - https://github.com/DominicTobias/universal-react/blob/master/app/actions/user.js

The action I used is fetchUserIfNeeded which won't make a request again if the user data already exists or a fetch is happening. That way componentDidMount only has to simply call the same function that the server does - https://github.com/DominicTobias/universal-react/blob/master/app/containers/User.js#L16

 static readyOnActions(dispatch, params) {
    return Promise.all([
      dispatch(UserActions.fetchUserIfNeeded(params.id))
    ]);
  }

  componentDidMount() {
    User.readyOnActions(this.props.dispatch, this.props.params);
  }

Closing but any questions feel free to add

isTravis commented 8 years ago

Thanks for the work - this is a great starter.

I have the asynchronous fetches working well and only calling to the server when needed (i.e. only when the data does not already exist). Is there a way though to prevent the transition of the route and rendering of the component until the asynchronous action finishes on the client though?

That is, when I navigate on the client to a new route that will fetch data, is there a way to delay the route transition until that data is fetched?

sekoyo commented 8 years ago

@isTravis thanks sorry I was away on holiday. There are probably a few ways to solve this but I think I would look into a HoC (higher order component) i.e a component which wraps the ones I want to have async fetches and shows a loading spinner or something until they are complete and then renders the wrapped component.

isTravis commented 8 years ago

Thanks for the response @DominicTobias. That is essentially what I wound up doing. My higher goal though is to not remove the old content (and show a loading spinner) until the new content is ready. Similar to how Github handles client-side page loads when switching between tabs of a repo (blue loading bar at top, and page doesn't change at all until new content is ready).

It's a pretty minor detail, but something I've seen and liked in other boilerplates. I think there has to be some hook directly into the router, which of course is a bit nasty and fragile.