Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) e?timestamp=1513567252592" class="Floatl
(server) e?timestamp=1513567262304" class="Floatl
printWarning @ warning.js:33
warning @ warning.js:57
_mountImageIntoNode @ ReactMount.js:505
mountComponentIntoNode @ ReactMount.js:110
perform @ Transaction.js:141
batchedMountComponentIntoNode @ ReactMount.js:124
perform @ Transaction.js:141
batchedUpdates @ ReactDefaultBatchingStrategy.js:60
batchedUpdates @ ReactUpdates.js:95
_renderNewRootComponent @ ReactMount.js:317
_renderSubtreeIntoContainer @ ReactMount.js:399
render @ ReactMount.js:420
_callee$ @ client.js:131
tryCatch @ runtime.js:65
invoke @ runtime.js:303
prototype.(anonymous function) @ runtime.js:117
step @ client.js:157
(anonymous) @ client.js:157
Promise resolved (async)
step @ client.js:157
(anonymous) @ client.js:157
(anonymous) @ client.js:157
onLocationChange @ client.js:99
603 @ client.js:157
__webpack_require__ @ bootstrap 1770fbcfd3c9b9a79094:54
1549 @ Hotpush.js:57
__webpack_require__ @ bootstrap 1770fbcfd3c9b9a79094:54
webpackJsonpCallback @ bootstrap 1770fbcfd3c9b9a79094:25
(anonymous) @ client.js:1
Are you running React v16?
General speaking, you can restrict a component to client side render like this
import React from 'react';
import NonSSRfriendly from 'NonSSRfriendly ';
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
class SomeComponent extends React.Component {
render() {
return (
{ canUseDOM ? (
<div>
<p>Only renders on the client</p>
<NonSSRfriendly />
</div>
) : (
<div />
)}
);
}
}
export default SomeComponent
@tim-soft Wouldn't the error still be present because the server would render:
<div />
And the client would render:
<div>
<p>Only renders on the client</p>
<NonSSRfriendly />
</div>
And the DOM checksum would be a mismatch. Also heads up I'd avoid using fbjs as it's not stable for public. They attached a note to their package on npm:
Note: If you are consuming the code here and you are not also a Facebook project, be prepared for a bad time. APIs may appear or disappear and we may not follow semver strictly, though we will do our best to. This library is being published with our use cases in mind and is not necessarily meant to be consumed by the broader public. In order for us to move fast and ship projects like React and Relay, we've made the decision to not support everybody. We probably won't take your feature requests unless they align with our needs. There will be overlap in functionality here and in other open source projects.
Used a few functions from there myself, until was bit by it. Just something to be aware of, risk maybe worth taking per context depending on how widespread the use is (or how big the teams), or could just copy pasta that code and publish as a stable npm package under your control (did this myself). Quite a few widely used libraries were broken when they made some changes to fbjs structure/code a year or so ago.
Understanding is the canonical way to render something different on the client vs server is to use componentDidMount and setState like this:
import React from 'react';
import NonSSRfriendly from 'NonSSRfriendly ';
class SomeComponent extends React.Component {
constructor() {
this.state = {
hasMounted: false
}
}
render() {
return (
{this.state.hasMounted ? (
<div>
<p>Only renders on the client</p>
<NonSSRfriendly />
</div>
) : (
null
)}
);
}
componentDidMount = () => (this.setState({hasMounted: true}))
}
export default SomeComponent;
That's on a per component basis. I think what @aLIEzsss4 is after is to ONLY do client side render and drop SSR completely. Like how react-create-app works. This means not calling render on the whole app (for react-starter-kit). React-create-app is the best case example to follow for this. They have a public HTML file that has some string replaces run on it to populate the paths to their version of client.js (only running on client).
If wanted to mimic that with react-starter-kit would have to do something similar. Difference being react-starter-kit does not have an html template file, it's all react components, so there is no way to completely avoid SSR with the current setup (but you can avoid the checksum).
So what you would have to do with react-starter-kit is SSR of html.js and remove the children render on this line: https://github.com/kriasoft/react-starter-kit/blob/master/src/components/Html.js#L60
This would only render the HTML template that client.js would hook into to do the first render of the app (similar to react-create-app). Also would need to remove hydrate from client.js and just do render on this line:
https://github.com/kriasoft/react-starter-kit/blob/master/src/client.js#L85
Hydrate is only used to populate something that has been rendered with ReactDOMServer and in this scenario the app is not being completely rendered on the server and rehydrated on the client (only the HTML template is), so would need to change that line to render instead of hydrate.
Another heads up they also added an escape hatch for client server mismatch (to be used sparingly, this is like using !important in CSS in my opinion -- truly exceptional scenarios). You have to add suppressHydrationWarning={true} to the element, this works one level deep and makes sense for things like Date.now() which would be different if generated on the server vs client.
@buildbreakdo those are some really great points, to the first point this _usually_ won't cause a mismatch(or maybe React v16 just doesn't complain about it?). This is more or less a quick and dirty fix for a stubborn component that calls window without checking if it exists first -- which you could also do instead of canUseDOM.
Conditionally disabling SSR on a per route basis could be really useful for those annoying edge cases. Trying to subscribeToMore if using Apollo subscriptions can also yield some cryptic errors with SSR for instance. Subs, among _some_ other things, really don't make sense on the server side
thank you
Most helpful comment
@tim-soft Wouldn't the error still be present because the server would render:
<div />And the client would render:
And the DOM checksum would be a mismatch. Also heads up I'd avoid using fbjs as it's not stable for public. They attached a note to their package on npm:
Used a few functions from there myself, until was bit by it. Just something to be aware of, risk maybe worth taking per context depending on how widespread the use is (or how big the teams), or could just copy pasta that code and publish as a stable npm package under your control (did this myself). Quite a few widely used libraries were broken when they made some changes to fbjs structure/code a year or so ago.
Understanding is the canonical way to render something different on the client vs server is to use componentDidMount and setState like this:
That's on a per component basis. I think what @aLIEzsss4 is after is to ONLY do client side render and drop SSR completely. Like how react-create-app works. This means not calling render on the whole app (for react-starter-kit). React-create-app is the best case example to follow for this. They have a public HTML file that has some string replaces run on it to populate the paths to their version of client.js (only running on client).
If wanted to mimic that with react-starter-kit would have to do something similar. Difference being react-starter-kit does not have an html template file, it's all react components, so there is no way to completely avoid SSR with the current setup (but you can avoid the checksum).
So what you would have to do with react-starter-kit is SSR of html.js and remove the children render on this line: https://github.com/kriasoft/react-starter-kit/blob/master/src/components/Html.js#L60
This would only render the HTML template that client.js would hook into to do the first render of the app (similar to react-create-app). Also would need to remove hydrate from client.js and just do render on this line:
https://github.com/kriasoft/react-starter-kit/blob/master/src/client.js#L85
Hydrate is only used to populate something that has been rendered with ReactDOMServer and in this scenario the app is not being completely rendered on the server and rehydrated on the client (only the HTML template is), so would need to change that line to render instead of hydrate.
Another heads up they also added an escape hatch for client server mismatch (to be used sparingly, this is like using !important in CSS in my opinion -- truly exceptional scenarios). You have to add
suppressHydrationWarning={true}to the element, this works one level deep and makes sense for things like Date.now() which would be different if generated on the server vs client.