I have the following render
in my "main" component:
import ComponentA from './component-a.js';
import ComponentB from './component-b.js';
const App = React.createClass({
render: function() {
return (
<div>
<ComponentA/>
<ComponentB/>
</div>
);
}
});
ComponentA
requires a css
file. So I have the following in component-a.js
:
require ('./component-a.css');
const ComponentA = React.createClass({
render: function() {
return (
<div>component a</div>
);
}
});
… whereas ComponentB
doesn't. So I have the following in component-b.js
:
const ComponentB = React.createClass({
render: function() {
return (
<div>component b</div>
);
}
});
The css
file required by ComponentA
(only) is:
div {
width: 100px;
height: 30px;
border: 1px solid red;
}
Even though it is only ComponentA
that requires the css
, ComponentB
is also affected. This is what gets rendered in the browser:
It seems that all div
elements in the page are affected by the style required by ComponentA
. That includes the div
of the subsequent component ComponentB
(which does not require the css
style) as well as the div
that contains ComponentA
and ComponentB
and yet another div
added by React:
Aren't css
files affecting only the component that requires them? If not, and they are effectively global in effect then what exactly are the semantics of requiring a css
file from a specific component ?
Other than using inline styles and placing everything in JS code, is there a way to compartmentalize CSS files so that they only affect the React component that requires them ? If one were to use class names to achieve that effect there is no guarantee that the class names would be unique when a component is used alongside other components.
CSS is still loaded into the browser to affect the whole page. The importing of css files is only to modularize your css along with your js, so that when you use your module loader to the fullest, not only are you not loading unnecessary js, you also aren't loading unnecessary css.
EDIT: a video on how Instagram works with module loading:
https://www.youtube.com/watch?v=VkTCL6Nqm6Y&noredirect=1
Your best solution is still to namespace your css. Concerning clashing issues, you could use even more verbose classnames than what I used below like mjb-appname-componentname
Have your ComonentA's render be:
render: function() {
return (
<div className="component-a">component a</div>
);
}
and its css file be
.component-a div {
width: 100px;
height: 30px;
border: 1px solid red;
}
preferably with a css preprocessor like less
or sass
.component-a {
div {
width: 100px;
height: 30px;
border: 1px solid red;
}
}
extra:
an interesting talk about inline style in js: http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
a discussion about issues raised by using this inline style method:
https://github.com/callemall/material-ui/issues/4066
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With