601

我知道您可以在 React 类中指定样式,如下所示:

const MyDiv = React.createClass({
  render: function() {
    const style = {
      color: 'white',
      fontSize: 200
    };
    
    return <div style={style}> Have a good and productive day! </div>;
  }
});

我是否应该以这种方式进行所有样式设置,并且在我的 CSS 文件中完全没有指定样式?

或者我应该完全避免内联样式?

两者都做一点点似乎很奇怪和混乱——在调整样式时需要检查两个地方。

4

20 回答 20

503

目前还没有很多“最佳实践”。我们这些对 React 组件使用内联样式的人仍在进行大量试验。

有许多方法千差万别:React inline-style lib comparison chart

全部还是全部?

我们所说的“风格”,其实包括不少概念:

  • 布局——一个元素/组件与其他组件的关系如何
  • 外观——元素/组件的特征
  • 行为和状态——元素/组件在给定状态下的外观

从状态样式开始

React 已经在管理组件的状态,这使得状态和行为样式自然适合与组件逻辑共置。

与其构建组件以使用条件状态类进行渲染,不如考虑直接添加状态样式:

// Typical component with state-classes
<li 
 className={classnames({ 'todo-list__item': true, 'is-complete': item.complete })} />


// Using inline-styles for state
<li className='todo-list__item'
 style={(item.complete) ? styles.complete : {}} />

请注意,我们正在使用一个类来设置外观样式,但不再使用任何.is-前缀类来表示state 和 behavior

我们可以使用Object.assign(ES6) 或_.extend(underscore/lodash) 添加对多种状态的支持:

// Supporting multiple-states with inline-styles
<li 'todo-list__item'
 style={Object.assign({}, item.complete && styles.complete, item.due && styles.due )}>

定制和可重用性

现在我们正在使用Object.assign它,让我们的组件可以以不同的样式重用变得非常简单。如果我们想覆盖默认样式,我们可以在调用站点使用 props 这样做,如下所示<TodoItem dueStyle={ fontWeight: "bold" } />:像这样实现:

<li 'todo-list__item'
 style={Object.assign({},
         item.due && styles.due,
         item.due && this.props.dueStyles)}>

布局

就个人而言,我认为内联布局样式没有令人信服的理由。有许多很棒的 CSS 布局系统。我只用一个。

也就是说,不要将布局样式直接添加到您的组件中。用布局组件包装你的组件。这是一个例子。

// This couples your component to the layout system
// It reduces the reusability of your component
<UserBadge
 className="col-xs-12 col-sm-6 col-md-8"
 firstName="Michael"
 lastName="Chan" />

// This is much easier to maintain and change
<div class="col-xs-12 col-sm-6 col-md-8">
  <UserBadge
   firstName="Michael"
   lastName="Chan" />
</div>

对于布局支持,我经常尝试将组件设计为100% widthheight.

外貌

这是“内联式”辩论中最具争议的领域。最终,这取决于您设计的组件以及您的团队使用 JavaScript 的舒适度。

有一件事是肯定的,你需要图书馆的帮助。浏览器状态 ( :hover, :focus) 和媒体查询在原始 React 中很痛苦。

我喜欢Radium,因为这些难处理部分的语法旨在模拟 SASS。

代码组织

通常你会在模块之外看到一个样式对象。对于 todo-list 组件,它可能看起来像这样:

var styles = {
  root: {
    display: "block"
  },
  item: {
    color: "black"

    complete: {
      textDecoration: "line-through"
    },

    due: {
      color: "red"
    }
  },
}

吸气剂函数

向您的模板添加一堆样式逻辑可能会有点混乱(如上所示)。我喜欢创建 getter 函数来计算样式:

React.createClass({
  getStyles: function () {
    return Object.assign(
      {},
      item.props.complete && styles.complete,
      item.props.due && styles.due,
      item.props.due && this.props.dueStyles
    );
  },

  render: function () {
    return <li style={this.getStyles()}>{this.props.item}</li>
  }
});

进一步关注

我在今年早些时候的 React Europe 上更详细地讨论了所有这些:内联样式以及何时最好“只使用 CSS”

我很乐意在您一路上发现新发现时为您提供帮助 :) 打我 -> @chantastic

于 2015-07-26T15:56:01.803 回答
196

React 中的 style 属性期望值是一个对象,即键值对。

style = {}里面会有另一个对象{float:'right'}让它工作。

<span style={{float:'right'}}>Download Audit</span>

希望这能解决问题

于 2017-01-11T12:31:56.060 回答
50

我在我的 React 组件中广泛使用内联样式。我发现在组件中并置样式更加清晰,因为组件具有和不具有哪些样式总是很清楚。再加上手头拥有 Javascript 的全部功能,确实简化了更复杂的样式需求。

起初我并不相信,但在涉足几个月后,我完全转换了,并且正在将我所有的 CSS 转换为内联或其他 JS 驱动的 css 方法。

Facebook 员工和 React 贡献者“vjeux”的演示文稿也非常有帮助 — https://speakerdeck.com/vjeux/react-css-in-js

于 2015-02-21T17:40:47.040 回答
26

style 属性的主要用途是动态的、基于状态的样式。例如,您可以基于某种状态在进度条上设置宽度样式,或者基于其他内容设置位置或可见性。

JS 中的样式施加了应用程序无法为可重用组件提供自定义样式的限制。在上述情况下这是完全可以接受的,但当您更改可见特征时,尤其是颜色时就不行了。

于 2014-11-12T09:15:09.103 回答
21

JSX 中的样式与 HTML 中的样式非常相似。

HTML 案例:

div style="背景颜色:红色;颜色:白色"

JSX 案例:

div style={{ backgroundColor: 'red', color: 'white' }}

于 2018-12-23T07:48:08.850 回答
20

James K Nelson 在他的信“为什么不应该使用 JavaScript 为 React 组件设置样式”中指出,实际上并没有需要使用内联样式的缺点。他的说法是,带有less/scss 的陈旧乏味的CSS 是最好的解决方案。他的论文中支持 CSS 的部分:

  • 可外部扩展
  • 可分割的(内联样式覆盖一切)
  • 设计师友好
于 2015-12-17T13:37:16.480 回答
9

我所做的是给我的每个可重用组件一个唯一的自定义元素名称,然后为该组件创建一个 CSS 文件,特别是包含该组件的所有样式选项(并且仅适用于该组件)。

var MyDiv = React.createClass({
  render: function() {
    return <custom-component style={style}> Have a good and productive day! </custom-component>;
  }
});

在“custom-component.css”文件中,每个条目都以 custom-component 标签开头:

custom-component { 
   display: block; /* have it work as a div */
   color: 'white'; 
   fontSize: 200; 
} 
custom-component h1 { 
  font-size: 1.4em; 
}

这意味着您不会失去关注点分离的关键概念。视图与风格。如果您共享您的组件,其他人更容易为其设置主题以匹配其网页的其余部分。

于 2015-07-07T01:47:12.470 回答
9

TLDR - 在 js 解决方案中使用 css(例如 Emotion 或 Styled Components),享受最好的 css 和 js 所提供的

在 css 或 scss 文件中,很难管理动态样式。在内联样式标签中,您不能使用媒体查询或伪选择器。

在 JS 中使用 CSS,您可以享受两全其美。JS 中的 Css 之于 CSS 就像 React 之于 HTML。它允许将您的 css 编写为 JS 代码中的对象或字符串,并享受 javascript 生态系统的强大功能和工具。

时至今日,在 js 库中有一些流行且支持良好的 CSS,包括 Emotion、Styled-Components 和 Radium。


让我们比较一下我们的代码将如何寻找简单元素的样式。我们将设计一个“hello world” div,使其在桌面上显示为大,在移动设备上显示为小。

使用样式属性

return (
   <div style={{fontSize:24}} className="hello-world">
      Hello world
   </div>
)

由于在样式标签中无法进行媒体查询,我们必须为元素添加一个类名并添加一个 css 规则。

@media screen and (max-width: 700px){
   .hello-world {
      font-size: 16px; 
   }
}

使用 Emotion 的 10 个 CSS 标签

return (
   <div
      css={{
         fontSize: 24, 
         [CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY]:{
            fontSize: 16 
         }
      }
   >
      Hello world
   </div>
)

Emotion 还支持模板字符串和样式组件。因此,如果您愿意,可以编写:

return (
   <Box>
      Hello world
   </Box>
)

const Box = styled.div`
   font-size: 24px; 
   ${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
      font-size: 16px; 
   }
`

“CSS in JS”在幕后使用 CSS 类。

最佳实践

以下是我推荐的一些最佳实践:

  1. 在 JS 解决方案中使用 CSS

  2. 在 JS 中构建您的样式代码与构建您的代码非常相似。例如:

  • 识别重复的样式,并将它们写在一个地方。在 Emotion 中有两种方法可以做到这一点:
// option 1 - Write common styles in CONSTANT variables
// styles.js
export const COMMON_STYLES = {
   BUTTON: css`
      background-color: blue; 
      color: white; 
      :hover {
         background-color: dark-blue; 
      }
   `
}

// SomeButton.js
const SomeButton = (props) => {
   ...
   return (
      <button
         css={COMMON_STYLES.BUTTON}
         ...
      >
         Click Me
      </button>
   )
}

// Option 2 - Write your common styles in a dedicated component 

const Button = styled.button`
   background-color: blue; 
   color: white; 
   :hover {
      background-color: dark-blue; 
   }   
`

const SomeButton = (props) => {
   ...
   return (
      <Button ...> 
         Click me
      </Button>
   )
}

  1. React 编码模式是封装组件 - 控制组件的 HTML 和 JS 编写在一个文件中。那是您的 CSS/样式代码样式该组件所属的地方。

  2. 必要时,向组件添加样式道具。这样,您可以重用在子组件中编写的代码和样式,并由父组件根据您的特定需求对其进行自定义。

const Button = styled.button([COMMON_STYLES.BUTTON, props=>props.stl])

const SmallButton = (props)=>(
   <Button 
      ...
      stl={css`font-size: 12px`}
   >
      Click me if you can see me
   </Button>
)

const BigButton = (props) => (
   <Button
      ...
      stl={css`font-size: 30px;`}
   >
      Click me
   </Button>
)
于 2019-06-23T04:52:22.833 回答
9

这是JSX语法中基于布尔值的样式:

style={{display: this.state.isShowing ? "inherit" : "none"}}
于 2019-03-19T11:08:53.990 回答
7

这实际上取决于您的应用程序有多大如果您想在构建中使用webpack 之类的捆绑器并将 CSS 和 JS 捆绑在一起,以及您想如何管理您的应用程序流程!在一天结束时,取决于你的情况,你可以做出决定!

我在大型项目中组织文件的偏好是将CSS 和 JS文件分开,这样更容易共享,UI 人员更容易浏览 CSS 文件,整个应用程序的文件组织也更整洁!

始终以这种方式思考,确保在开发阶段一切都在他们应该在的地方,正确命名并且便于其他开发人员找到东西......

我个人根据需要混合它们,例如...尝试使用外部 css,但如果需要 React 也会接受样式,您需要将其作为具有键值的对象传递,如下所示:

import React from 'react';

const App = props => {
  return (
    <div className="app" style={{background: 'red', color: 'white'}}>  /*<<<<look at style here*/
      Hello World...
    </div>
  )
}

export default App;
于 2017-06-16T08:30:03.947 回答
3

内联样式的问题是内容安全策略 (CSP) 变得越来越普遍,但不允许这样做。因此,我建议完全避免使用内联样式。

更新: 为了进一步解释,CSP 是服务器发送的 HTTP 标头,用于限制页面上可以显示的内容。如果开发人员对网站的编码不佳,它只是进一步的缓解措施,可以应用于服务器以阻止攻击者做一些顽皮的事情。

大多数这些限制的目的是阻止 XSS(跨站点脚本)攻击。XSS 是攻击者想出一种方法在您的页面上包含他自己的 javascript 的地方(例如,如果我创建了用户名bob<SCRIPT>alert("hello")</SCRIPT>然后发表评论,并且您访问了该页面,它不应该显示警报)。开发人员应该拒绝让用户向网站添加这样的内容,但以防万一他们犯了错误,如果发现任何script>标签,CSP 会阻止页面加载。

CSP 只是为开发人员提供的额外保护,以确保如果他们犯了错误,攻击者不会对该站点的访问者造成问题。

所以这一切都是 XSS,但是如果攻击者不能包含<script>标签但可以包含<style>标签或style=在标签上包含参数怎么办?然后他可能会改变网站的外观,让您被诱骗点击错误的按钮或出现其他问题。这不是什么大问题,但仍然需要避免,CSP 会为您做到这一点。

测试 CSP 站点的一个很好的资源是https://securityheaders.io/

您可以在http://www.html5rocks.com/en/tutorials/security/content-security-policy/阅读有关 CSP 的更多信息

于 2015-03-19T01:06:33.693 回答
3

我通常将 scss 文件关联到每个 React 组件。但是,我看不出你为什么不用逻辑封装组件并查看它的原因。我的意思是,您对 Web 组件也有类似的情况。

于 2015-06-19T08:13:41.600 回答
3

对于某些组件,使用内联样式更容易。此外,我发现动画组件样式更容易和更简洁(因为我使用的是 Javascript 而不是 CSS)。

对于独立组件,我使用“Spread Operator”或“...”。对我来说,它清晰、美丽,而且在狭小的空间里工作。这是我制作的一个小加载动画来展示它的好处:

<div style={{...this.styles.container, ...this.state.opacity}}>
    <div style={{...this.state.colors[0], ...this.styles.block}}/>
    <div style={{...this.state.colors[1], ...this.styles.block}}/>
    <div style={{...this.state.colors[2], ...this.styles.block}}/>
    <div style={{...this.state.colors[7], ...this.styles.block}}/>
    <div style={{...this.styles.block}}/>
    <div style={{...this.state.colors[3], ...this.styles.block}}/>
    <div style={{...this.state.colors[6], ...this.styles.block}}/>
    <div style={{...this.state.colors[5], ...this.styles.block}}/>
    <div style={{...this.state.colors[4], ...this.styles.block}}/>
  </div>

    this.styles = {
  container: {
    'display': 'flex',
    'flexDirection': 'row',
    'justifyContent': 'center',
    'alignItems': 'center',
    'flexWrap': 'wrap',
    'width': 21,
    'height': 21,
    'borderRadius': '50%'
  },
  block: {
    'width': 7,
    'height': 7,
    'borderRadius': '50%',
  }
}
this.state = {
  colors: [
    { backgroundColor: 'red'},
    { backgroundColor: 'blue'},
    { backgroundColor: 'yellow'},
    { backgroundColor: 'green'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
  ],
  opacity: {
    'opacity': 0
  }
}

编辑 2019 年 11 月

在该行业(财富 500 强公司)工作,我不允许制作任何内联样式。在我们的团队中,我们认为内联样式不可读且不可维护。而且,在亲眼目睹了内联样式如何使支持应用程序完全无法忍受之后,我不得不同意。我完全不鼓励内联样式。

于 2017-12-01T17:26:11.207 回答
3

根据您的配置,内联样式可以为您提供热重载。每次样式更改时,网页都会立即重新渲染。这有助于我更快地开发组件。话虽如此,我相信您可以为 CSS + SCSS 设置热重载环境。

于 2016-08-17T18:17:25.273 回答
3

您也可以使用 StrCSS,它会创建独立的类名等等!示例代码看起来像。您可以(可选)从 Visual Studio Marketplace 安装 VSCode 扩展以获得语法高亮支持!

来源:strcss

import { Sheet } from "strcss";
import React, { Component } from "react";

const sheet = new Sheet(`
  map button
    color green
    color red !ios
    fontSize 16
  on hover
    opacity .5
  at mobile
    fontSize 10
`);

export class User extends Component {
  render() {
    return <div className={sheet.map.button}>
      {"Look mom, I'm green!
      Unless you're on iOS..."}
    </div>;
  }
}
于 2018-03-28T12:47:28.173 回答
3

您可以使用内联样式,但如果您在所有样式中都使用它们,则会有一些限制,一些已知的限制是您不能在其中使用CSS 伪选择器媒体查询

你可以使用Radium 来解决这个问题,但我觉得项目发展起来会变得很麻烦。

我会推荐使用CSS 模块

使用CSS 模块,您将可以自由地在 CSS 文件中编写 CSS,并且不必担心命名冲突,它会由 CSS 模块处理。

此方法的一个优点是它为您提供了特定组件的样式功能。这将为下一个开发人员在您的项目上工作创建更多可维护的代码和可读的项目架构。

于 2018-07-19T06:59:42.367 回答
2

2020 年更新:最佳做法是使用已经为您完成了艰苦工作的库,并且在您进行切换时不会杀死您的团队,正如视频中最初接受的答案所指出的那样(它仍然相关)。也只是为了了解趋势,这是一个非常有用的图表。在对此进行了自己的研究之后,我选择在我的新项目中使用 Emotion,并且事实证明它非常灵活且可扩展。

鉴于 2015 年最受好评的答案推荐Radium,现在已降级为维护模式。因此,添加一个替代列表似乎是合理的。停止镭的帖子建议了一些图书馆。每个链接的站点都有现成的示例,因此我将避免在此处复制和粘贴代码。

  • Emotion受到样式组件等“启发” ,在 js 中使用样式并且可以与框架无关,但肯定会促进其 React 库。在这篇文章中,情绪一直保持最新。
  • styled-components具有可比性,并提供许多与 Emotion 相同的功能。也在积极维护中。Emotion 和 styled-components 都有相似的语法。它是专门为使用 React 组件而构建的。
  • JSS js 中样式的另一种选择,它与框架无关,尽管它确实有许多框架包,其中包括 React-JSS。
于 2020-02-06T22:09:27.583 回答
1

有时我们需要为组件中的某些元素设置样式,但是如果我们必须只显示该组件或者样式太少,那么我们不使用 CSS 类,而是在 react js 中使用内联样式。reactjs 内联样式与 HTML 内联样式相同,只是属性名称有点不同

使用 style={{prop:"value"}} 在任何标签中写下你的风格

import React, { Component } from "react";
    import { Redirect } from "react-router";

    class InlineStyle extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }

      render() {
        return (
          <div>
            <div>
              <div
                style={{
                  color: "red",
                  fontSize: 40,
                  background: "green"
                }}// this is inline style in reactjs
              >

              </div>
            </div>
          </div>
        );
      }
    }
    export default InlineStyle;
于 2019-08-01T10:12:46.230 回答
0

无论如何,从不推荐内联 CSS。我们在项目中使用了基于 JSS 的 styled-components。它通过在组件上添加动态类名来保护 css 覆盖。您还可以根据传递的道具添加 css 值。

于 2020-05-03T13:49:43.190 回答
0

我更喜欢使用样式组件。它为设计提供了更好的解决方案。

import React, { Component, Fragment } from 'react'
import styled from 'styled-components';

const StyledDiv = styled.div`
    display: block;
    margin-left: auto;
    margin-right: auto;
    font-size:200; // here we can set static
    color: ${props => props.color} // set dynamic color by props
`;

export default class RenderHtml extends Component {
    render() {
        return (
            <Fragment>
                <StyledDiv color={'white'}>
                    Have a good and productive day!
                </StyledDiv>
            </Fragment>
        )
    }
}
于 2020-12-03T07:22:54.600 回答