I have used the following code to import css
componentWillMount() {
import('./patient-summary.css');
}
How to remove imported css from react when component is not in use. When i go back to previous screen this css gets applied there. Any idea ?
UPDATE:: Webpack config
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public/dist')
},
module: {
rules: [
{
test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
}
,
{
test: /\.(png|jpeg|jpg|gif|svg)$/,
loader: "file-loader"
}
]
},
devServer: {
contentBase: path.resolve(__dirname, "public"),
historyApiFallback: true,
port: 3000,
watchOptions: {
// Delay the rebuild after the first change
aggregateTimeout: 300,
// Poll using interval (in ms, accepts boolean too)
poll: 1000,
},
},
plugins: [
// Ignore node_modules so CPU usage with poll
// watching drops significantly.
new webpack.WatchIgnorePlugin([
path.join(__dirname, "node_modules")
])
],
};
I found a (sort of) reasonable way to do this in React. In short, you can lazy-load React components 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 the main code, with more explanation below. Here's my Gist.
useDisableImportedStyles.tsx
import { useEffect } from 'react'
// global list of all the StyleSheets that are touched in useDisableImportedStyles
const switchableGlobalStyleSheets: StyleSheet[] = []
// just to clarify what createUseDisableImportedStyles() returns
type useDisableImportedStyles = () => void
export const createUseDisableImportedStyles = (
immediatelyUnloadStyle: boolean = true
// if true: immediately unloads the StyleSheet when the component is unmounted
// if false: waits to unloads the StyleSheet until another instance of useDisableImportedStyles is called.This avoids a flash of unstyled content
): useDisableImportedStyles => {
let localStyleSheet: StyleSheet
return () => {
useEffect(() => {
// if there are no stylesheets, you did something wrong...
if (document.styleSheets.length < 1) return
// set the localStyleSheet if this is the first time this instance of this useEffect is called
if (localStyleSheet == null) {
localStyleSheet = document.styleSheets[document.styleSheets.length - 1]
switchableGlobalStyleSheets.push(localStyleSheet)
}
// if we are switching StyleSheets, disable all switchableGlobalStyleSheets
if (!immediatelyUnloadStyle) {
switchableGlobalStyleSheets.forEach(styleSheet => styleSheet.disabled = true)
}
// enable our StyleSheet!
localStyleSheet.disabled = false
// if we are NOT switching StyleSheets, disable this StyleSheet when the component is unmounted
if (immediatelyUnloadStyle) return () => {
if (localStyleSheet != null) localStyleSheet.disabled = true
}
})
}
}
WARNING: This is pretty finicky. You must set this up exactly or there may be unintended consequences
createUseDisableImportedStyles
must called in global scope in the same tsx file as the imported css being targeted and the component to be lazy loadedimport React from 'react'
import { createUseDisableImportedStyles } from './useDisableImportedStyles'
import './global-styles.css'
const useDisableImportedStyles = createUseDisableImportedStyles()
export const CssComponent: React.FC<{}> = () => {
useDisableImportedStyles()
return null
}
export default CssComponent
LazyCssComponent = React.lazy(() => import('./cssComponent'))
...
<React.Suspense fallback={<></>}>
{condition && <LazyCssComponent/>}
</React.Suspense>
InitialCssComponent
never needs to actually render, it just needs to be importedimport InitialCssComponent from './initialCssComponent'
LazyCssComponent = React.lazy(() => import('./cssComponent'))
//...
{false && <InitialCssComponent/>}
<React.Suspense fallback={<></>}>
{condition && <LazyCssComponent/>}
</React.Suspense>
GOOD LUCK!
First of all, AFAIK, you should not call any imports in componentWillMount. This means that every time a new component about to mount, this css will be loaded over and over. Instead, it must be placed at the beginning of your module.
The way that you avoid unnecessary css imports is to avoid unnecessary component imports. Hence, if your component is not called anywhere, then this css will not be loaded.
For routing, I think you will need to do some code splitting, but I am not sure if it is straightforward or the right way to do.
Link 1 Link 2
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