我通常有与每个React组件关联的scss文件。但是,我不明白为什么你不会用逻辑封装组件并查看它。我的意思是,你有与Web组件类似的东西。
目前还没有很多“最佳实践”。对于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 : {}} />
请注意,我们正在使用类来设置样式 的 出现 强> 但不再使用任何 .is- 前缀类 的 国家和行为 强> 。
.is-
我们可以用 Object.assign (ES6)或 _.extend (下划线/ lodash)添加对多个状态的支持:
Object.assign
_.extend
// 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" } /> 。像这样实现:
<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% width 和 height 。
100%
width
height
这是“内联式”辩论中最具争议的领域。最终,它取决于您的设计组件以及使用JavaScript的团队的舒适度。
有一件事是肯定的,你需要图书馆的协助。浏览器状态( :hover , :focus ),媒体查询在原始的React中很痛苦。
:hover
:focus
我喜欢 镭 因为这些硬件的语法设计用于模拟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
詹姆斯·尼尔森在他的信中 “为什么你不应该用JavaScript来设计反应组件的风格” 声明实际上并不需要使用内联样式及其缺点。他的陈述是,使用less / scss的旧无聊的CSS是最好的解决方案。他的论文部分支持css:
根据您的配置,内联样式可以为您提供热重新加载。每次样式更改时都会立即重新呈现网页。这有助于我更快地开发组件。话虽如此,我相信你可以为CSS + SCSS设置热重载环境。
JSX中的样式与HTML中的样式非常相似。
的 HTML案例: 强>
div style =“background-color:red; color:white”
的 JSX案例: 强>
div style = {{backgroundColor:'red',color:'white'}}
内联样式的问题是内容安全策略(CSP)变得越来越普遍,不允许它。因此,我建议完全避免使用内联样式。
的 更新: 强> 为了进一步说明,CSP是服务器发送的HTTP标头,用于限制页面上可以显示的内容。这只是一个进一步的缓解,可以应用于服务器,以阻止攻击者做一些顽皮的事情,如果开发人员编写网站很差。
大多数这些限制的目的是阻止XSS(跨站点脚本)攻击。 XSS是攻击者想出一种在页面上包含自己的javascript的方法(例如,如果我创建了我的用户名) bob<SCRIPT>alert("hello")</SCRIPT> 然后发表评论,你访问该页面,它不应该显示警报)。开发人员应该否认让用户向网站添加这样的内容的能力,但是如果他们犯了错误,那么CSP会阻止页面加载 script> 标签。
bob<SCRIPT>alert("hello")</SCRIPT>
script>
CSP只是为开发人员提供额外的保护,以确保他们犯了错误,攻击者不会对访问该网站的访问者造成问题。
所有这些都是XSS,但是如果攻击者不能包括那么 <script> 标签,但可以包括 <style> 标签或包括 style= 标签上的参数?然后他可能会以这样的方式改变网站的外观,以至于你被欺骗点击错误的按钮或其他一些问题。这不是一个值得关注的问题,但仍然需要避免,CSP会为您做到这一点。
<script>
<style>
style=
用于测试CSP站点的良好资源是 https://securityheaders.io/
您可以在以下位置了解有关CSP的更多信 http://www.html5rocks.com/en/tutorials/security/content-security-policy/
style属性的主要用途是动态的,基于状态的样式。例如,您可以根据某个状态在进度条上显示宽度样式,或者基于其他内容的位置或可见性。
JS中的样式强加了应用程序无法为可重用组件提供自定义样式的限制。在上述情况下,这是完全可以接受的,但是当您更改可见特征(尤其是颜色)时则不能。
我在React组件中广泛使用内联样式。我发现在组件中共置样式更加清晰,因为它总是清楚组件所具有和不具有的样式。此外,拥有Javascript的全部功能确实简化了更复杂的样式需求。
我一开始并不相信,但在涉足它几个月后,我完全转换了,并且正在将我的所有CSS转换为内联或其他JS驱动的css方法。
Facebook员工和React贡献者“vjeux”的这个演示也非常有用 https://speakerdeck.com/vjeux/react-css-in-js
React中的style属性期望值为对象,即键值对。
style = {} 里面会有另一个对象 {float:'right'} 使它工作。
style = {}
{float:'right'}
<span style={{float:'right'}}>{'Download Audit'}</span>
希望这能解决问题
我所做的是为每个可重用组件提供一个唯一的自定义元素名称,然后为该组件创建一个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; }
这意味着你不会失去关注分离的关键概念。查看与风格。如果您共享组件,则其他主题更容易与其他网页匹配。
对于某些组件,使用内联样式更容易。此外,我发现它更容易和更简洁(因为我使用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 } }
然后,在componentWillMount()中,我设置了一个像这样的间隔......
this.interval = setInterval(() => { let colors = this.state.colors; let opacity = this.state.opacity; if(this.props.reverse) { let color = colors[colors.length-1]; colors.pop(); colors.unshift(color) } else { let color = colors[0]; colors.shift(); colors.push(color); } opacity['opacity'] < 1 ? opacity['opacity']+=0.06 : null; this.setState({colors, opacity}); }, this.speed);
您也可以使用StrCSS,它可以创建隔离的类名等等!示例代码看起来像。您可以(可选)从Visual Studio Marketplace安装VSCode扩展,以获得语法突出显示支持!
资源: https://github.com/jeffreylanters/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>; } }
您可以使用内联样式,但如果您在所有样式中使用它们,您将有一些限制,一些已知的限制是您无法使用 的 CSS伪选择器 强> 和 的 媒体查询 强> 在那里。
您可以使用 的 镭 强> https://github.com/FormidableLabs/radium 为了解决这个问题,我仍然觉得这个项目越来越繁琐。
我建议使用 的 CSS模块 强> https://github.com/css-modules/css-modules
运用 的 CSS模块 强> 你可以自由地在CSS文件中编写CSS,而不必担心命名冲突,它将由CSS模块处理。
此方法的一个优点是它为您提供了特定组件的样式功能。这将为下一个开发人员创建更加可维护的代码和可读的项目体系结构,以便为您的项目工作。