我知道你可以在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文件中指定的样式吗?

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

这似乎有点奇怪和混乱做一点两者-两个地方需要检查时调整样式。


当前回答

TLDR -使用css在js解决方案(如情感或样式组件),享受最好的css和js所提供的

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

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

到目前为止,js库中有一些受欢迎的、得到良好支持的CSS,包括Emotion、styles - components和镭。


让我们比较一下样式化简单元素时代码的样子。我们将设置“hello world”div的样式,这样它在桌面上显示大,在移动端显示小。

使用style属性

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

由于媒体查询在样式标签中是不可能的,我们必须向元素中添加一个className并添加一个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; 
   }
`

“JS中的CSS”背后使用的是CSS类。

最佳实践

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

在JS中使用CSS解决方案 在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>
   )
}

React编码模式是封装组件- HTML和JS,控制组件被写在一个文件中。这是你的css/样式代码样式的组件属于。 必要时,为组件添加样式道具。通过这种方式,您可以重用在子组件中编写的代码和样式,并通过父组件对其进行定制以满足您的特定需求。

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

其他回答

我通常有与每个React组件相关联的scss文件。但是,我不明白为什么你不封装组件与逻辑,并查看它。我的意思是,你有类似的web组件。

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

鉴于2015年投票最多的答案是推荐镭,现在已经进入维护模式。因此,增加一些备选方案似乎是合理的。停止使用镭的帖子建议使用几个图书馆。每个链接的网站都有现成的示例,所以我将避免在这里复制和粘贴代码。

Emotion which is "inspired by" styled-components among others, uses styles in js and can be framework agnostic, but definitely promotes its React library. Emotion has been kept up to date as of this post. styled-components is comparable and offers many of the same features as Emotion. Also actively being maintained. Both Emotion and styled-components have similar syntax. It is built specifically to work with React components. JSS Yet another option for styles in js which is framework agnostic though it does have a number of framework packages, React-JSS among them.

James K Nelson在他的信“为什么你不应该用JavaScript样式化React组件”中指出,实际上没有必要使用内联样式及其缺点。他的观点是,旧的无趣的CSS加上较少的/scss是最好的解决方案。他的论文中支持CSS的部分:

可扩展的外部 可分割(内联样式超越一切) define_image_transformation

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

更新: 为了进一步解释,CSP是服务器发送的HTTP报头,用于限制页面上可以出现的内容。这只是进一步的缓解措施,可以应用到服务器上,以阻止攻击者在开发人员对站点编写糟糕的代码时做一些调皮的事情。

The purpose of most of these restrictions is to stop XSS (cross-site scripting) attacks. XSS is where an attacker figures out a way to include his own javascript on your page (for example, if I make my username bob<SCRIPT>alert("hello")</SCRIPT> and then post a comment, and you visit the page, it shouldn't show an alert). Developers should deny the ability to have a user add content like this to the site, but just in case they made a mistake, then CSP blocks the page from loading if it finds any script> tags.

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

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

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

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

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

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