簡體   English   中英

如何在React中動態創建新的全局CSS類?

[英]How can I create new global css classes on the fly in React?

我正在為項目使用Draft.js。 我創建了一個組件,使您可以從菜單中選擇一種字體,然后將該字體應用於Draft.js編輯器中的所選文本。

我需要這樣做的方式:

  1. 為所選字體動態添加@font-face規則,其中包括字體名稱和文件位置;
  2. 創建一個新的 CSS類,其中包含font-family屬性,該屬性使用添加的@font-face規則中的字體名稱;
  3. 將該新CSS類應用於所選內容。

除了#2之外,我已經掌握了一切。 對於#2,我找不到任何明確的方法或工具可用於在全局空間中創建新的CSS類。 我正在閱讀有關CSS-in-js的很多文章,但是所有內容似乎都過時或過於復雜。

我正在像這樣格式化@font-face規則和類:

const newClass = {
    '@font-face': [
        {
            fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A`,
            src: `url(/fonts/${font.value}-TD-Space.woff)`,
            fontWeight: 'normal',
            fontStyle: 'normal',

        }, {
            fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-B`,
            src: `url(/fonts/${font.value}-TD.woff)`,
            fontWeight: 'normal',
            fontStyle: 'normal',
        },
    ],
    [`.${font.value}`]: {
        fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A, ${font.label} ${FONT_FAMILY_PREFIX}-B`,
    },
})

但是我不確定在哪里放置它,以便可以在整個應用程序中訪問它。

這是否需要某些軟件包的幫助,或者有沒有一種更簡單的方法可以管理它?

最簡單的方法可能是使用React的Context功能( 此處的文檔

基本上,您定義這樣的上下文:

// style-context.js

export const Styles = {
  style1: {
    fontFamily: '"Times New Roman", Times, serif',
    fontSize: '12px'
  },
  style2: {
    fontFamily: 'Arial, Helvetica, sans-serif',
    fontSize: '16px'
  },
};

export const StyleContext = React.createContext({
    theme: styles.style1, // default value
    changeTheme: (newTheme) => {}
  }
);

然后,您可以像這樣包裝您的應用程序:

// App.js

import React, { Component } from 'react'
import { FontContext, styles } from './style-context'

class App extends Component {
  constructor(props) {
    super(props)

    // Function to change the theme
    this.chooseTheme = (newTheme) => {
      this.setState({
        theme: styles[newTheme]
      })
    }

    // State includes the current theme and function to change it
    this.state = {
      theme: styles.style1,
      chooseTheme: this.chooseTheme
    }
  }

  render() {
    return (
      // Wrap with the context's Provider, and pass in the theme from
      // the state. Those state values will be available from all
      // children, no matter how deep.
      <StyleContext.Provider value={this.state}>
        <div className="App">
          {/* components */}
        </div>
      </StyleContext.Provider>
    );
  }
}

然后,有兩種使用上下文的方法。 首先,您可以在任何子組件中引用它,如下所示:

// SomeComponent.js

import React, { Component } from 'react'
import {StyleContext} from './style-context'

class SomeComponent extends Component {
  render() {
    return (
      <div style={
        this.context.theme
      }>
        {/* ... */}
      </div>
    )
  }
}
SomeComponent.contextType = StyleContext

export default SomeComponent

真的很簡單。 另一種訪問它的方式是這樣的,如果您要在單個組件上組合多個上下文,這將非常有用:

// TestButton.js

import React, {Component} from 'react'
import {StyleContext} from './style-context'

class TestButton extends Component {
  render() {
    return (
      <StyleContext.Consumer>
        {
          // The contents of the Consumer tag will receive the
          // 'value' prop set at the Provider level, which is,
          // in this case, the App state containing the current
          // theme and function to change it
          ({theme, chooseTheme}) => (
            <button onClick={() => {chooseTheme('style2')}} style={theme}>Change Font</button>
          )
        }
      </StyleContext.Consumer>
    )
  }
}

export default TestButton

這樣做意味着您無需以編程方式更改給定不同div的類,也無需首先生成CSS類。

另外,我最喜歡的分配樣式的技巧之一是使用Object.assign()這樣做,如下所示:

...
<div style={Object.assign(
  { backgroundColor: 'red', fontSize: '16px' },
  this.context.theme
)}>
...

這樣,您可以設置默認值,將Context與Component分離,並允許主題的style屬性僅覆蓋匹配的鍵,並將其余鍵組合在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM