javascript - 如何在 React 中动态创建新的全局 css 类?

标签 javascript css reactjs

我正在为一个元素使用 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 的上下文功能 (docs here)

基本上,您可以像这样定义一个上下文:

// 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 解耦,并允许主题的样式属性仅覆盖匹配的键,组合其余键。

关于javascript - 如何在 React 中动态创建新的全局 css 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53024769/

相关文章:

javascript - 在自定义点击时 react 条件样式

javascript - react : How to show Spinner & Component (at the same time) when State Changes using `useEffect`

javascript - 如何以编程方式将焦点应用到 Firefox 中 iframe 中的父框架(解决 window.focus())?

javascript - 防止 jQuery 在 AJAX 调用后自动重定向

javascript - Promise.all 中的 promise 多次被拒绝,到底发生了什么?

javascript - 如何加载场景 react native

javascript - 如何在另一个插件中使用 JQuery 插件而不破坏其中一个插件?

css - 如何在 Meteor-React 设置中使用 D3-force 渲染 D3?

css - 本地主机 (Wamp) 上的 Symfony Assets

html - 当您有多个设计但您的 CMS 只能上传一个包含所有样式和模板的文件时,如何构建您的模板?