Do you want to request a feature or report a bug?
Bug, most likely. Or at least explanation why I get a warning and help fixing it.
What is the current behavior?
I've got a really simple app that's SSR'd:
export const App = () => (
<div className={styles.container}>Hello world!</div>
);
immediately when rendering it, I get a warning in console:
Warning: Extra attributes from the server: class
that really doesn't make sense to me, because once you renderToString(), the className properties are mapped to normal "class" attribute - so during hydration, I expected React to ignore or map back to className, if necessary. Below is more or less what comes back rendered from server:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="/static/style.css" /><script type="text/javascript" src="/static/app.js" defer></script></head>
<body>
<div id="app"><div class="container_1G7pW" data-reactroot="">Hello world!</div></div>
</body>
</html>
I noticed "data-reactroot" is ignored (makes sense), shouldn't the class be removed from the extraAttributeNames at some point as well?
switch (name) {
// Built-in SSR attribute is whitelisted
case 'data-reactroot':
break;
// Controlled attributes are not validated
// TODO: Only ignore them on controlled tags.
case 'value':
break;
case 'checked':
break;
case 'selected':
break;
default:
// Intentionally use the original name.
// See discussion in https://github.com/facebook/react/pull/10676.
extraAttributeNames.add(attributes[_i].name);
}
What is the expected behavior?
No warning for "class" attribute.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React/ReactDOM v16.8.2
@grzegorzjudas Curious! Is it possible that styles.container is returning null some how client side? That would make the class name disappear on a client render.
A complete reproducing example, please. We can鈥檛 help otherwise.
I had this same problem and it was due to a mismatch in the configuration of the client and server webpack loaders.
Client side I was missing style-loader and using a default config for css-loader and this was resulting in the imported styles to not be an object containing the generated style names.
NB: I'm not suggesting this is a working production config, just an example of how client and server can generate differing results.
Here are the less rules for the server:
rules: [
{
test: /\.less$/,
include: config.includes,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
sourceMap: true,
localIdentName: '[name]_[local]_[contenthash:base64:5]',
camelCase: true,
},
}, 'less-loader'
],
}),
},
//...
],
And for the client:
rules: [
{
test: /\.less$/,
include: config.includes,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
sourceMap: true,
localIdentName: '[name]_[local]_[contenthash:base64:5]',
camelCase: true,
},
}, 'less-loader'
],
},
// ...
],
@dmeehan1968 interesting, I will try this out and if it doesn't work, will prepare a repro.
Actually, there's a WIP repo I'm working on in grzegorzjudas/react-enterprise-starter that has this issue.
@nhunzaker the class is working as it should, the styling is applied correctly...
Okay great, so you were able to get to the bottom of this?
Gonna close this out because I think it might be resolved, but let me know if this isn't the case!
Hi,
sorry for late answer. It did indeed do the trick! Previously:
use: [
{ loader: 'css-loader', options: { modules: true, sourceMap: true } }
]
now:
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader', options: { modules: true, importLoaders: 1, sourceMap: true } }
]
Such a beginners overlook... thanks for help!