conditional css in create-react-app

两盒软妹~` 提交于 2021-02-08 11:26:32

问题


I have default css file and separate css file that should be applied (to owerride default) only when certain conditions are met.

I am using create-react-app wit default import 'file.css' syntax.

What is the best way forward to decide whether to load or not load particular css file dynamically?


回答1:


You can use require('file.css') syntax instead. This will allow you to put it inside of a conditional.

e.g.

if(someCondition) {
    require('file.css');
}



回答2:


The require method only worked in development (as all the CSS is bundled upon build), and the import method did not work at all (using CRA version 3.3).

In our case, we have multiple themes, which cannot be bundled - so we solved this using React.lazy and React.Suspense.

We have the ThemeSelector, which loads the correct css conditionally.

import React from 'react';

/**
 * The theme components only imports it's theme CSS-file. These components are lazy
 * loaded, to enable "code splitting" (in order to avoid the themes being bundled together)
 */
const Theme1 = React.lazy(() => import('./Theme1'));
const Theme2 = React.lazy(() => import('./Theme2'));

const ThemeSelector: React.FC = ({ children }) => (
  <>
    {/* Conditionally render theme, based on the current client context */}
    <React.Suspense fallback={() => null}>
      {shouldRenderTheme1 && <Theme1 />}
      {shouldRenderTheme2 && <Theme2 />}
    </React.Suspense>
    {/* Render children immediately! */}
    {children}
  </>
);

export default ThemeSelector;

The Theme component's only job, is to import the correct css file:

import * as React from 'react';

// 👇 Only important line - as this component should be lazy-loaded,
//    to enable code - splitting for this CSS.
import 'theme1.css';

const Theme1: React.FC = () => <></>;

export default Theme1;

The ThemeSelector should wrap the App component, in the src/index.tsx:

import React from 'react';
import ReactDOM from 'react-dom';
import ThemeSelector from 'themes/ThemeSelector';

ReactDOM.render(
  <ThemeSelector>
    <App />
  </ThemeSelector>,
  document.getElementById('root')
);

As I understand, this forces each Theme to be split into separate bundles (effectively also splitting CSS).




回答3:


Use React Helmet. It adds links, meta tags etc into document header dynamically. Add it into any render method.

import {Component} from 'react';
import ReactHelmet from 'react-helmet';

class Example extends Component{
    render(
        <ReactHelmet link={
            [{"rel": "stylesheet", type:"text/css", "href": "/style.css"}]
        }/>);
    }
}

You can rewrite it on next <ReactHelmet/> rendering.



来源:https://stackoverflow.com/questions/46835825/conditional-css-in-create-react-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!