React.js内联样式最佳实践

eye*_*mew 483 css inline-styles reactjs react-jsx

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

var MyDiv = React.createClass({
  render: function() {
    var style = {
      color: 'white',
      fontSize: 200
    };

    return <div style={style}> Have a good and productive day! </div>;
  }
});
Run Code Online (Sandbox Code Playgroud)

我是否应该以这种方式做所有样式,并且我的CSS文件中没有指定任何样式?

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

做两件事似乎很奇怪和混乱 - 在调整样式时需要检查两个地方.

cha*_*tic 449

目前还没有很多"最佳实践".对于React组件,我们这些使用内联样式的人仍然在进行实验.

有许多方法变化很大:React内联样式的lib比较图表

全有或全无?

我们所谓的"风格"实际上包含了很多概念:

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

从状态样式开始

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 : {}} />
Run Code Online (Sandbox Code Playgroud)

请注意,我们使用类来设置外观样式,但不再使用任何带.is-前缀的类来处理状态和行为.

我们可以使用Object.assign(ES6)或_.extend(下划线/ lodash)来添加对多个状态的支持:

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

定制和可重用性

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

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

布局

就个人而言,我没有看到内联布局样式的令人信服的理由.有很多很棒的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>
Run Code Online (Sandbox Code Playgroud)

对于布局支持,我经常尝试将组件设计为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"
    }
  },
}
Run Code Online (Sandbox Code Playgroud)

吸气功能

在模板中添加一堆样式逻辑可能会有点混乱(如上所示).我喜欢创建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>
  }
});
Run Code Online (Sandbox Code Playgroud)

进一步观看

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

我很乐意帮助您沿途创造新的发现:)打我 - > @chantastic

  • 好读.也非常感谢你[@相关谈话](https://www.youtube.com/watch?v=ERB1TJBn32c),@ chantastic.#公认 (9认同)
  • "用布局组件包裹你的组件":如此明显,但正是我需要的. (5认同)
  • @alexrussell谢谢!我认为这里的答案仍然很好.改变的一个领域是Aphrodite似乎是社区首选的内联梯形图书馆(通过Radium) - 虽然它确实是个人偏好的问题. (4认同)
  • @chantastic很棒的答案.一年过去了,这一切还是真的吗?只是真的只是进入React和内联样式的想法,并且只是想知道自从你发布这个答案以来是否有任何改变. (2认同)
  • @alexrussell哎呀.意外提前提交.我现在使用这种组件技术来设计我的组件.这个想法非常简单.您创建一个只关心款式的应用,并与这些组成成分,而不是`div`,`span`,`了`等这将有助于保持风格孤立的,无论你使用哪一个库.http://reactpatterns.com/#Style组件 (2认同)
  • 优化浏览器渲染,即提高移动设备的性能,需要将页面中的元素数量保持在 800 个以下。Reactjs 已经要求您为每个组件提供一个包装器 div。从本质上来说,它已经存在缺陷。将 oocss 之类的类(即网格类)应用到 div 上来包装组件会加剧该问题。底线:不要使用反应。绝对不要使用内联样式。 (2认同)

ana*_*han 122

React中的style属性期望值为对象,即键值对.

style = {}将在其中有另一个对象,{float:'right'}以使其工作.

<span style={{float:'right'}}>{'Download Audit'}</span>
Run Code Online (Sandbox Code Playgroud)

希望这能解决问题

  • 所以如果我想在JS文件中使用CSS类,如何使用媒体查询相同 (3认同)
  • 这种方法的一个缺点是,每次定义内联样式都会创建一个新对象。这会在“style”属性中产生差异,这可能会导致性能问题。至少,在“渲染”之外定义一个像这样的常量样式。希望这可以帮助! (2认同)

Kyl*_*ews 48

我在React组件中广泛使用内联样式.我发现在组件中共置样式更加清晰,因为它总是清楚组件所具有和不具有的样式.此外,拥有Javascript的全部功能确实简化了更复杂的样式需求.

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

Facebook员工和React贡献者"vjeux"的这次演示也非常有用 - https://speakerdeck.com/vjeux/react-css-in-js

  • 我将如何使用内联样式制作响应式布局?您没有此处的媒体查询选项. (5认同)
  • @ g3mini现在不是推荐的方法,因为有更强大的解决方案,用于样式组件,如`CSS Modules`,`styled-components`等. (3认同)

Bri*_*and 22

style属性的主要用途是动态的,基于状态的样式.例如,您可以根据某个状态在进度条上显示宽度样式,或者基于其他内容的位置或可见性.

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

  • 这不是真的.您可以明确地应用自定义样式来响应组件.组件只需要将自己的样式对象与从上面传递的对象合并,该对象可以来自应用程序数据.请参阅下面提到的https://speakerdeck.com/vjeux/react-css-in-js的最后一张幻灯片 (2认同)

ale*_*511 17

詹姆斯·尼尔森在他的信中写道"为什么你不应该用JavaScript来反应组件"说明实际上并不需要使用内联样式及其缺点.他的陈述是,使用less/scss的旧无聊的CSS是最好的解决方案.他的论文部分支持css:

  • 外部可扩展
  • leverable(内联样式超越一切)
  • 设计师友好


Anu*_*rya 9

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

style={{display: this.state.isShowing ? "inherit" : "none"}}
Run Code Online (Sandbox Code Playgroud)


wid*_*ged 8

我所做的是为每个可重用组件提供一个唯一的自定义元素名称,然后为该组件创建一个css文件,特别是该组件的所有样式选项(并且仅针对该组件).

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

在文件'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; 
}
Run Code Online (Sandbox Code Playgroud)

这意味着你不会失去关注分离的关键概念.查看与风格.如果您共享组件,则其他主题更容易与其他网页匹配.


小智 8

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

HTML案例:

div style =“ background-color:red; color:white”

JSX案例:

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

  • 从背景颜色到背景颜色!这就是我需要的! (3认同)

Ali*_*eza 5

这真的取决于如何你的应用程序是,如果你想用捆扎机喜欢的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;
Run Code Online (Sandbox Code Playgroud)


Ben*_*arp 5

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>
)
Run Code Online (Sandbox Code Playgroud)

由于在样式标记中无法进行媒体查询,因此我们必须向元素添加 className 并添加 css 规则。

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

使用 Emotion 的 10 个 CSS 标签

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

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

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

const Box = styled.div`
   font-size: 24px; 
   ${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
      font-size: 16px; 
   }
`
Run Code Online (Sandbox Code Playgroud)

在幕后,“JS 中的 CSS”使用 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>
   )
}

Run Code Online (Sandbox Code Playgroud)
  1. React 编码模式是封装的组件 - 控制组件的 HTML 和 JS 编写在一个文件中。这就是你的 css/style 代码来设置该组件所属的样式。

  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>
)
Run Code Online (Sandbox Code Playgroud)