【问题标题】:Use inline style in React with plain CSS string在 React 中使用纯 CSS 字符串的内联样式
【发布时间】:2015-10-25 15:41:23
【问题描述】:

我正在重写基于 ReactJS 中的 AngularJS 的现有应用程序。在应用程序中,用户可以提供 CSS 样式字符串来设置某些元素的样式。在 AngularJS 中这没问题,我只是将 'style' 属性设置为给定的字符串。在 ReactJS 我不能再这样做了,因为 ReactJS 需要一个样式对象。我不想改变应用程序的行为并要求用户现在提供一个与 ReactJS 兼容的样式对象。 ReactJS 中是否有任何方法可以只使用纯 CSS 样式字符串来设置元素的样式?

【问题讨论】:

  • 将样式字符串转换为 javascript 对象。 stackoverflow.com/questions/9518956/…
  • 我认为这无济于事,因为 ReactJS 对象具有与 CSS 键不同的驼峰式键。
  • 修改转换器以处理驼峰情况。
  • 这也许是可能的,但我实际上希望有一种更清洁的方式来做到这一点。
  • 我参加这个聚会有点晚了,但没有将字符串转换为对象,我能看到的唯一其他“干净”解决方案是使用 react 生成一个 style 标记提供的字符串的内容。

标签: javascript css reactjs


【解决方案1】:

您可以在componentDidMountcomponentDidUpdate 中使用setAttribute('style', ...) 设置样式字符串。

您只需要能够获得对 React 创建的 DOM 节点的引用。你可以使用refs

这是一个例子。该组件接受一个styleString 属性,并将其设置为它所呈现的<div/> 上的样式。

import React from 'react';

class StyledDiv extends React.Component {
  componentDidMount() {
    this.refs.theDiv.setAttribute('style', this.props.styleString);
  }

  componentDidUpdate() {
    this.refs.theDiv.setAttribute('style', this.props.styleString);
  }

  render() {
    return (
      <div ref="theDiv" />
    );
  }
}
StyledDiv.propTypes = {
  styleString: React.PropTypes.string,
};
export default StyledDiv;

【讨论】:

    【解决方案2】:

    如果您使用的是styled-components,那么甚至不必费心查看其他答案。使用 v4,您实际上可以将一个字符串传递给 css prop 到任何 html 标记或样式组件。

    <div css="margin-top: 4px;">
    Yes it works just like that :).
    </div>
    

    猜猜你甚至不需要导入styled-components。您需要做的就是添加this babel 插件。它将任何带有 css prop 的元素转换为样式化组件。

    阅读更多here

    【讨论】:

      【解决方案3】:

      制作了一个可以处理这个问题的模块Style Iteasy peasy,认为我们都应该回到简单地编写CSS。

      只需将样式字符串作为道具传入即可。

      npm install style-it --save

      函数语法 (JSFIDDLE)

      import React from 'react';
      import ReactDOM from 'react-dom';
      import Style from 'style-it';
      
      class Intro extends React.Component {
        render() {
          return Style.it(
            this.props.cssText,
            <p className="intro">CSS-in-JS made simple -- just Style It.</p>
          );
        }
      }
      
      ReactDOM.render(
        <Intro cssText=".intro { color: red; }"/>,
        document.getElementById('container')
      );
      

      JSX 语法 (JSFIDDLE)

      import React from 'react';
      import ReactDOM from 'react-dom';
      import Style from 'style-it';
      
      class Intro extends React.Component {
        render() {
          return (
            <Style>
            {this.props.cssText}
      
            <p className="intro">CSS-in-JS made simple -- just Style It.</p>
          </Style>
        }
      }
      
      export default Intro;
      
      ReactDOM.render(
        <Intro cssText=".intro { color: red; }"/>,
        document.getElementById('container')
      );
      

      【讨论】:

        【解决方案4】:

        这是我为试剂找到的一个 hack,但我相信它对于原始反应版本 >= 16(其中自定义 dom 属性被抛出)同样适用。只需使用大写的STYLE 属性而不是小写的style,这会被React 拦截。

        【讨论】:

          【解决方案5】:

          补充 taylor michels 的回答

          function CSSstring(string) {
            const css_json = `{"${string
              .replace(/; /g, '", "')
              .replace(/: /g, '": "')
              .replace(";", "")}"}`;
          
            const obj = JSON.parse(css_json);
          
            const keyValues = Object.keys(obj).map((key) => {
              var camelCased = key.replace(/-[a-z]/g, (g) => g[1].toUpperCase());
              return { [camelCased]: obj[key] };
            });
            return Object.assign({}, ...keyValues);
          }
          
          
          return <div style={CSSstring("margin-top: 4px; top: 100px")}></div>
          

          【讨论】:

            【解决方案6】:

            将样式字符串转换为javascript对象

            这就是我的解决方案。我有一个像这样生成的 json 对象

            const generatedStyles = {
                "background-image": "url(\"http:/someurl/foo.JPEG\"), 
                "background-size": "auto 30px",
                "background-position": "center center"
            }
            

            我需要一种方法来将它转换为一个新对象,该对象带有用于 react-styles 对象的驼峰式键。我已经在我的组件中定义了这个。

            renameKeys(obj) {
                const keyValues = Object.keys(obj).map(key => {
                    var camelCased = key.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
                    return { [camelCased]: obj[key] };
                });
                return Object.assign({}, ...keyValues);
            }
            

            并且可以像&lt;a style={this.renameKeys(generatedStyles)}&gt;styled link&lt;/a&gt;一样在渲染中使用

            【讨论】:

            • 干净地使用替换和正则表达式,也建议使用 lambda,除非您使用替换函数的第二个参数,否则 [a-z] 周围的 var camelCased = key.replace(/-[a-z]/g, g =&gt; g[1].toUpperCase()); 括号是不必要的
            猜你喜欢
            • 2020-09-29
            • 2021-06-10
            • 2023-03-12
            • 2018-07-04
            • 2018-02-15
            • 2019-08-04
            • 2015-04-06
            • 2017-06-15
            • 2020-08-12
            相关资源
            最近更新 更多