CSS Modules
There are several ways to write styles in React. The most common is CSS modules. This method combines CSS styles with components and applies them directly to components.
| - SRC | | _components | | _ButtonComponent | | _Button. JSX | | _Button) sassCopy the code
Example: CSS mudules in React
You can see that styles applied through modules are all in the form:
Import styles from './GlobalSelectors. CSS '; # 2. Use the form className={styles.container} for the module class name # and the form className="text-left" for the global selector export default class GlobalSelectors extends Component { render() { return ( <div className={ styles.container }> <p className="text-left">Global Selectors</p> </div> ); }} // The CSS file is GlobalSelectors. Css. container {border-width: 2px; border-style: solid; border-color: brown; padding: 0 20px; margin: 0 6px; max-width: 400px; } # ':global' indicates that the class is global. Container: global. text-left {float: left}Copy the code
CSS modules themselves require CSS-Loader to work with them, which may have disadvantages:
- You must use camelCase to name CSS class names
- The styles object must be used when imported into className
- CSS Modules mixed with global CSS classes can be difficult to manage
- Referencing undefined CSS modules does not get a warning
The React CSS Modules component automatically loads CSS Modules via styleName.
react-css-modules
Using react-CSS-modules will solve the CSS modules problem above, for example:
import React from 'react'; import CSSModules from 'react-css-modules'; Import styles from './tabel.sass' class Table extends React.Component {render() {return (# className = "class name" StyleName indicates the module className <div styleName="table" className="tabel--info"> <div styleName="row"> <div styleName="cell">A0</div> <div styleName="cell">B0</div> </div> </div> ); Export default CSSModules(Table, styles);Copy the code
Concrete implementation steps and notes are discussed below
1. Install
Install via NPM:
npm install --save react-css-modules
Copy the code
2. Webpack configuration
Need to use this bag style – loader | CSS – loader
1. Configure the CSS file
For the development phase:
{test: /\. CSS $/, loaders: [ 'style?sourceMap', 'css?modues&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]' ] }Copy the code
For production: use the 2.x version of the extract-text-webpack-plugin
npm install --save-dev extract-text-webpack-plugin@2 npm install --save-dev resolve-url-loader post-loader // webpack.config.js file var ExtractTextPlugin = require('extract-text-webpack-plugin'); {test: /\. CSS $/, loader: ExtractTextPlugin({notExtractLoader: 'style-loader', loader: 'CSS? modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base4:5]! resolve-url! New ExtractTextPlugin({filename: 'app.css', allChunks: true})]Copy the code
2. For using SASS or other preprocessors
Install the required loader:
NPM install --save-dev resolve-url-loader sass-loader node-sass // sourceMap {test: /\. Sass $/, loaders: [ 'style', 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]', 'resolve-url', } // use sourceMap {test: /\.sass$/, loaders: [ 'style?sourceMap', 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]', 'resolve-url', 'sass?sourceMap' ] }Copy the code
Of course, the production phase configuration is similar
3. Override component styles with ‘styles’
Such as:
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';
class Table extends React.Component {
render () {
return <div styleName='table'>
<div styleName='row'>
<div styleName='cell'>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
export default CSSModules(Table, styles);
Copy the code
This is common. If you want to override styles, you can override the component style using styles in the component:
Import customStyles from './table-custom-styles.css'; <Table styles={customStyles} /> <Table styles={customStyles} />Copy the code
4. Loops and subcomponents
StyleName cannot be used to modify child components within a component, such as:
import React from 'react'; import CSSModules from 'react-css-modules'; import List from './List'; import styles from './table.css'; class CustomList extends React.Component { render () { let itemTemplate; ItemTemplate = (name) => {return <li styleName='item-template'>{name}</li>; }; return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code
This can be rewritten in two ways:
Method 1: Use the styles property
import React from 'react'; import CSSModules from 'react-css-modules'; import List from './List'; import styles from './table.css'; class CustomList extends React.Component { render () { let itemTemplate; # use the styles property ItemTemplate = (name) => {return <li className={this.props. Styles ['item-template']}>{name}</li>; }; return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code
Method 2: Call CSSModules inside the parent component to modify the child component:
import React, {Component} from 'react'; impot CSSModules from 'react-css-modules'; import List from './List'; import styles from './tabel.css'; class CustomList extends Component { render() { let itemTemplate; itemTemplate = (name) => { return <li styleName="item-template">{name}</li>; }; # internal call CSSModules itemTemplate = CSSModules(itemTemplate, this.props. Styles); return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code
5. CSSModules option
CSSModules are written in two ways:
CSSModules(Component, styles, options)
// 或者
CSSModules(Component, styles)
Copy the code
options :
AllowMultiple: The default value is false
If multiple classes are allowed to be declared, false:
<div styleName='foo bar' /> // Error if not allowedCopy the code
2. ErrorWhenNotFount: Default is true,
An error is reported if styleName is not found in CSS modules
6. Use global CSS
:global .foo {
// ...
}
Copy the code
This is used less often
7. Use the styles attribute for optional class names
We often encounter class names like this:
<div className={this.props.showMsg ? 'msg--visble': 'msg--hidden'}>
</div>
Copy the code
How do you handle this with react-CSS-modules?
The key is that the component decorated with CSSModules inherits the styles property, which maps CSS modules and CSS classes, namely:
class App extends React.Component {
render() {
<div>
<p styleName='foo'></p>
<p className={this.props.styles.foo}></p>
</div>
}
}
Copy the code
In this case,styleName='foo'
和 className={this.props.styles.foo}
It’s equivalent!!
So the solution to the above problem is:
class App extends Component { // ... Render () {# let visible = this.props. ShowMsg? 'msg-visible' : 'msg-hidden'; Return (<div # and then use className here instead of styleName # notice that since visible contains characters like '-', Styles ={this.props. Styles [visible]} >... className={this.props. </div> ) } }Copy the code
conclusion
- react-css-modules github
- css modules examples
- Learn how to write className when it changes with events (Rule 7)
- A way to learn the following writing styles in React
- How to configure CSS-related loaders in Webpack