Search code examples
reactjsreactjs-fluxisomorphic-javascript

How to avoid React markup checksum warnings when rendering time


When leveraging isomorphic rendering for a React component that displays time, I occasionally run into an issue where the server renders time at point A, but by the time the client picks up as a SPA, the time from point A has changed to point B, and React throws a React attempted to reuse markup in a container but the checksum was invalid warning:

enter image description here

The occurrence of the error is obviously more pronounced as you display more granular time units like seconds, but it would be nice to be sure I won't run into this on minute, hour, day, etc. boundaries as well.

Is there a way to tell React on the client side, effectively, "It's OK, this little portion of the DOM here can differ from the server side"? Or perhaps another way I haven't thought of?

More Detail

I'm using the React-Intl FormattedRelative component to display an item's creation date in a friendly fashion. The item's creation date of course stays the same between client and server (and gets passed to the client in a serialized Flux store), but the server render and client render time difference is just long enough that the rendered HTML frequently — but not always — differs.


Solution

  • This has been fixed with React Intl v2. It adds a initialNow property to stabilize the rendered times.

    A new feature has been added to <FormattedRelative> instances in React Intl v2, they now "tick" and stay up to date. Since time moves forward, it was confusing to have a prop named now, so it has been renamed to initialNow. Any <FormattedRelative> instances that use now should update to prop name to initialNow:

    Usage:

    <FormattedRelative value={date} initialNow={Date.now()}/>
    

    You can also provide this on IntlProvider in which case all FormattedRelative instances are stabilized.

    Note: The <IntlProvider> component also has a initialNow prop which can be assigned a value to stabilize the "now" reference time for all <FormattedRelative> instances. This is useful for universal/isomorphic apps to proper React checksums between the server and client initial render.

    Usage:

    <IntlProvider initialNow={Date.now()}>
      <FormattedRelative value={date}/>
    </IntlProvider>
    

    Reference: https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#update-how-relative-times-are-formatted