javascriptreactjscss-loader

How to fix error override CSS when change component in ReactJS


Login.js

import React from 'react'

export default class Login extends React.Component {
   componentWillMount(){
        import ('./styles/login_page.css');
    }
   ....
   <Link to="/register">Create account</Link>
}

Register.js

import React from 'react''

export default class Register extends React.Component {
   componentWillMount(){
        import ('./styles/register_page.css');
    }
   ....
   <Link to="/login">Login Now</Link>
}

App.js

import React from 'react'
import ReactDOM from 'react-dom'
import { Route, Switch, BrowserRouter } from 'react-router-dom'
import Login from './Login'
import Register from './Register'
import PageNotFound from './PageNotFound'

ReactDOM.render(
  <BrowserRouter>
    <Switch>
        <Route exact path='/login' component={Login }/>
        <Route exact path='/' component={Home} />
        <Route exact path='/register' component={Register }/>
        <Route component={PageNotFound} />
      </Switch>
  </BrowserRouter>,
  document.getElementById('root'));

After rendering, I click Login then click Create account and click again Login, login component's CSS is overrided by register component's CSS and home page is same. I want when going to any component, component's CSS is loading. Is there way to fix?


Solution

  • This is typically resolved by using descendant combinator in CSS. You need to set a distinct class in the root element of each component, and declare all other CSS styles by writing their selectors as descendants of that class.

    Login.js

    import React from 'react'
    
    export default class Login extends React.Component {
       componentWillMount(){
            import ('./styles/login_page.css');
        }
       ....
       <Link class="login-component" to="/register">Create account</Link>
    }
    

    login_page.css

    .login-component .item1 { ... }
    .login-component .item2 { ... }
    

    Register.js

    import React from 'react''
    
    export default class Register extends React.Component {
       componentWillMount(){
            import ('./styles/register_page.css');
        }
       ....
       <Link class="register-component" to="/login">Login Now</Link>
    }
    

    register_page.css

    .register-component .item1 { ... }
    .register-component .item2 { ... }
    

    So even if both components have elements matching .item1 and .item2, they will select the correct rule due to the descendant combinator. This might be a bit verbose with raw CSS, but if you're using any preprocessor it should be pretty simple.

    Else, you might just want to make the selectors distinct somehow.