admin管理员组

文章数量:1326099

I have two files which i load with react.lazy and suspense:

import React, { Suspense, lazy }  from "react";
import { Route, Redirect } from 'react-router-dom';
const MainLayout = lazy(()  => import('Components/Layout/MainLayout'))

export const PrivateRoute = () => (
  <Route  render={() => {
    return (
      localStorage.getItem('user')  != null// validation that it is a valid user
          ?
          <Suspense fallback={<div>Loading...</div>}>            
          <MainLayout/>
          </Suspense>
          : <Redirect to={{ pathname: '/login'}} />)
  }} />
)

Second:

import React, { Suspense, lazy } from "react";
const DefaultLayout = lazy(()  => import('Components/Layout/DefaultLayout'))

export const PublicRoute = () => (
    <Suspense fallback={<div>Loading...</div>}>            
        <DefaultLayout/>
    </Suspense>
  )

the /login path is refrencing a ponent (login) that is inside of the DefaultLayout ponent.

Scenario:

When the user is not logged in I load the DefaultLayout ponent which in turn contains my login ponent which imports cssFile1.css.

When the user enters the credentials i forward them to a path that is contained in my PrivateRoute where in turn i have cssFile2.css

The problem here is that cssFile1.css was loaded when i was using the loginpage but when the user logs in i want to unload cssFile1.css, is this possible and if yes then how?

I have two files which i load with react.lazy and suspense:

import React, { Suspense, lazy }  from "react";
import { Route, Redirect } from 'react-router-dom';
const MainLayout = lazy(()  => import('Components/Layout/MainLayout'))

export const PrivateRoute = () => (
  <Route  render={() => {
    return (
      localStorage.getItem('user')  != null// validation that it is a valid user
          ?
          <Suspense fallback={<div>Loading...</div>}>            
          <MainLayout/>
          </Suspense>
          : <Redirect to={{ pathname: '/login'}} />)
  }} />
)

Second:

import React, { Suspense, lazy } from "react";
const DefaultLayout = lazy(()  => import('Components/Layout/DefaultLayout'))

export const PublicRoute = () => (
    <Suspense fallback={<div>Loading...</div>}>            
        <DefaultLayout/>
    </Suspense>
  )

the /login path is refrencing a ponent (login) that is inside of the DefaultLayout ponent.

Scenario:

When the user is not logged in I load the DefaultLayout ponent which in turn contains my login ponent which imports cssFile1.css.

When the user enters the credentials i forward them to a path that is contained in my PrivateRoute where in turn i have cssFile2.css

The problem here is that cssFile1.css was loaded when i was using the loginpage but when the user logs in i want to unload cssFile1.css, is this possible and if yes then how?

Share Improve this question asked Oct 9, 2019 at 20:48 CodingLittleCodingLittle 1,8572 gold badges23 silver badges51 bronze badges 3
  • you can simply disable the sheet in document.styleSheets – dandavis Commented Oct 9, 2019 at 21:20
  • @dandavis that does work but I'm not sure how youre supposed to figure out which style sheet is which, doesnt seem to be a way to set any attributes such as "title" in webpack. Maybe a dummy rule you could filter by. Inserting with css-loader via css-style-sheet option allows you to keep a js reference and that does work, just takes some webpack config – light24bulbs Commented Feb 23, 2023 at 21:44
  • @light24bulbs: I've use smoking guns like xxx { content: "here i am"; } before... – dandavis Commented Feb 23, 2023 at 22:22
Add a ment  | 

4 Answers 4

Reset to default 2

I found a (sort of) reasonable way to do this in React. In short, you can lazy-load React ponents that contain the import './style.css', and when it loads, you can capture the imported StyleSheet to toggle its StyleSheet.disabled property later.

Here's my original solution to this problem.

Here's a Gist.

Ok, This might not be the most optimum approach, but can't the whole CSS inside the cssFile1.cssbe scoped? As in all the rules are written targetting elements if they are inside a certain container with a class say 'cssFile1'.

Likewise the 2nd CSS file will target all the elements only if they are located inside a container with the class 'cssFile2'.

now all you have to do to "unload/switch" the css is changing the main container class and the respective CSS rules will apply.

One last tip is, if you are using SASS / LESS its just a matter of enclosing the rules inside a container and all the rules will be scoped upon pilation.

As of late 2022, you can use the new CSSStyleSheet web API to control styles entirely from JS, including unloading. You can load this into a react app using css-in-js if you make a change to the css-loader options in webpack.

You can do things like

import darkStyles from '../scss/main/dark.css-style-sheet.scss';
import lightStyles from '../scss/main/light.css-style-sheet.scss';

// now mount one of those to the dom
document.adoptedStyleSheets = [darkStyles]
sheet.disabled = true;

It's a little involved for this answer, but I wrote a blog post about how to get it working with react: https://www.lunasec.io/docs/blog/css-style-sheets/

Basically, you need to use craco (or eject) to set up a new rule that sets exportType: 'css-style-sheet' on css-loader.

If I understand right, then no, it's impossible, because of Webpack imported css when React piled, anyway, you can try to css in js libs, such a Aphrodite.

本文标签: javascriptIs it possible to unload dynamic css imports in reactStack Overflow