在React中使用内联样式,使用纯CSS字符串

15

我正在将一个基于AngularJS的现有应用程序重写为ReactJS。在该应用程序中,用户可以提供CSS样式字符串来样式化某些元素。在AngularJS中,这没有问题,我只需将“style”属性设置为给定的字符串即可。但在ReactJS中,不能这样做,因为ReactJS需要一个样式对象。我不想改变应用程序的行为,并要求用户现在提供符合ReactJS样式对象的样式。在ReactJS中是否有一种方法可以仅使用普通的CSS样式字符串来设置元素的样式?


将样式字符串转换为JavaScript对象。https://dev59.com/1Gkw5IYBdhLWcg3w_Pbn - J. Mark Stevens
我认为这并没有帮助,因为ReactJS对象具有与CSS键不同的驼峰式键。 - Jan Schaefer
修改转换器以处理驼峰命名。 - J. Mark Stevens
可能有这种可能性,但我实际上希望有一种更简洁的方法来完成这个任务。 - Jan Schaefer
我来晚了,但除了将字符串转换为对象之外,我能看到的唯一其他“干净”的解决方案是使用React生成一个包含所提供字符串内容的style标签。 - Josh David Miller
6个回答

18

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

您只需要获取到 React 创建的 DOM 节点的引用即可。您可以使用 refs 进行获取。

以下是一个示例。此组件接受一个名为 styleString 的 prop,并将其设置为呈现的 <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;

7

我发现了一个关于reagent的技巧,但我相信它同样适用于原始的react版本>= 16(传递自定义dom属性的地方)。只需使用大写的STYLE属性即可,而不是小写的style,后者会被React拦截。


6
如果您正在使用styled-components,那么甚至不必查看其他答案。在v4中,您只需将字符串传递给css属性即可应用于任何html标记或样式化组件。
<div css="margin-top: 4px;">
Yes it works just like that :).
</div>

猜猜看,你甚至不需要导入 styled-components。你只需要添加 babel 插件即可。它会将任何具有 css 属性的元素转换为 styled 组件。

在这里阅读更多信息


3
我已经制作了一个模块来处理这个问题,叫做 Style It,非常简单易用,我认为我们应该回归到简单地编写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')
);

2
补充泰勒·米歇尔的答案。
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>

0
将样式字符串转换为JavaScript对象。
这对我来说是个解决方案。我生成了一个JSON对象,就像这样:
const generatedStyles = {
    "background-image": "url(\"http:/someurl/foo.JPEG\"), 
    "background-size": "auto 30px",
    "background-position": "center center"
}

我需要一种方法将这个对象转换为一个新的对象,其中包含用于React样式对象的驼峰命名键。我已经在我的组件中定义了这个方法。

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);
}

并且可以在渲染中使用,例如<a style={this.renameKeys(generatedStyles)}>样式链接</a>


干净地使用replace和regex,我也建议使用lambda,var camelCased = key.replace(/-[a-z]/g, g => g[1].toUpperCase()); [a-z]周围的括号是不必要的,除非你正在使用replacer函数的第二个参数。 - Valen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接