我知道您可以在React类中指定样式,如下所示:
var MyDiv = React.createClass({
render: function() {
var style = {
color: 'white',
fontSize: 200
};
return <div style={style}> Have a good and productive day! </div>;
}
});
我是否应该以这种方式做所有样式,并且我的CSS文件中没有指定任何样式?
或者我应该完全避免使用内联样式吗?
做两件事似乎很奇怪和混乱 - 在调整样式时需要检查两个地方。
答案 0 :(得分:422)
还没有很多“最佳实践”。对于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-
前缀类来处理状态和行为。
我们可以使用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 )}>
现在我们正在使用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%
width
和height
。
这是“内联式”辩论中最具争议的领域。最终,它取决于您的设计组件以及使用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更详细地讨论了所有这些问题:Inline Styles and when it's best to 'just use CSS'。
我很乐意帮助您沿途创造新的发现:)打我 - > @chantastic
答案 1 :(得分:98)
React中的style属性期望值为对象,即键值对。
style = {}
会在其中包含另一个对象{float:'right'}
,以使其有效。
<span style={{float:'right'}}>{'Download Audit'}</span>
希望这能解决问题
答案 2 :(得分:46)
我在React组件中广泛使用内联样式。我发现在组件中共置样式更加清晰,因为它总是清楚组件所具有和不具有的样式。此外,拥有Javascript的全部功能确实简化了更复杂的样式需求。
我一开始并不相信,但在涉及它几个月后,我已完全转换,并且正在将我的所有CSS转换为内联或其他JS驱动的css方法。
Facebook员工和React撰稿人“vjeux”的演示也非常有用 - https://speakerdeck.com/vjeux/react-css-in-js
答案 3 :(得分:22)
style属性的主要用途是动态的,基于状态的样式。例如,您可以根据某个状态在进度条上设置宽度样式,或者根据其他状态设置位置或可见性。
JS中的样式强加了应用程序无法为可重用组件提供自定义样式的限制。在上述情况下,这是完全可以接受的,但是当您更改可见特征(尤其是颜色)时则不是这样。
答案 4 :(得分:17)
James K Nelson在他的信"Why You Shouldn’t Style React Components With JavaScript"中指出,实际上并没有必要使用内联样式及其缺点。他的陈述是,使用less / scss的旧无聊的CSS是最好的解决方案。他的论文部分支持css:
答案 5 :(得分:8)
我所做的是为每个可重用组件提供一个唯一的自定义元素名称,然后为该组件创建一个css文件,特别是该组件的所有样式选项(并且仅针对该组件)。
var MyDiv = React.createClass({
render: function() {
return <custom-component style={style}> Have a good and productive day! </custom-component>;
}
});
在文件&#39; custom-component.css&#39;中,每个条目都将以自定义组件标记开头:
custom-component {
display: block; /* have it work as a div */
color: 'white';
fontSize: 200;
}
custom-component h1 {
font-size: 1.4em;
}
这意味着你没有放弃分离关注的关键概念。查看与风格。如果您共享您的组件,则其他主题更容易与其网页的其余部分匹配。
答案 6 :(得分: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;
答案 7 :(得分:3)
对于某些组件,使用内联样式更容易。此外,我发现它更容易,更简洁(因为我使用Javascript而不是CSS)来动画组件样式。
对于独立组件,我使用&#39; Spread Operator&#39;或者&#39; ...&#39;。对我而言,它清晰,美观,并且在狭小的空间中工作。这是一个小小的加载动画,我展示了它的好处:
<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);
答案 8 :(得分:3)
JSX中的样式与HTML中的样式非常相似。
HTML案例:
div style =“ background-color:red; color:white”
JSX案例:
div style = {{backgroundColor:'red',color:'white'}}
答案 9 :(得分:3)
根据您的配置,内联样式可以为您提供热重新加载。每次样式更改时都会立即重新呈现网页。这有助于我更快地开发组件。话虽如此,我确信您可以为CSS + SCSS设置热重载环境。
答案 10 :(得分:3)
我通常有与每个React组件关联的scss文件。但是,我不明白为什么你不会用逻辑封装组件并查看它。我的意思是,你有与Web组件类似的东西。
答案 11 :(得分:2)
您也可以使用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>;
}
}
答案 12 :(得分:2)
您可以使用内联样式,但是如果在所有样式中都使用它们,则会受到一些限制,一些已知的限制是您不能使用 CSS伪选择器和媒体查询。
您可以使用 Radium https://github.com/FormidableLabs/radium解决此问题,但我仍然认为该项目的发展会变得麻烦。
我建议使用 CSS模块 https://github.com/css-modules/css-modules
使用 CSS模块,您将可以自由地在CSS文件中编写CSS,而不必担心命名冲突,CSS模块会予以注意。
此方法的优点是,它为您提供了特定组件的样式功能。这将为下一开发人员创建更多可维护的代码和可读的项目体系结构。
答案 13 :(得分:2)
内联样式的问题是内容安全策略(CSP)变得越来越普遍,不允许它。因此,我建议完全避免使用内联样式。
<强>更新强> 为了进一步说明,CSP是服务器发送的HTTP标头,用于限制页面上可以显示的内容。它只是一个进一步的缓解,可以应用于服务器,以阻止攻击者做一些顽皮的事情,如果开发人员对网站编码不好。
大多数这些限制的目的是阻止XSS(跨站点脚本)攻击。 XSS是攻击者在您的页面上找到一种方法来包含他自己的javascript(例如,如果我使用我的用户名bob<SCRIPT>alert("hello")</SCRIPT>
然后发表评论,并且您访问该页面,则不应该显示警告)。开发人员应该拒绝让用户向网站添加这样的内容,但是如果他们犯了错误,那么如果CSP找到任何script>
标签,CSP就会阻止加载页面。
CSP只是为开发人员提供额外级别的保护,以确保他们犯了错误,攻击者不会对该网站的访问者造成问题。
所有这些都是XSS,但是如果攻击者不能包含<script>
标记但可以包含<style>
标记或在标记上包含style=
参数怎么办?然后他可能会以这样的方式改变网站的外观,以至于你被欺骗点击错误的按钮或其他一些问题。这不是一个值得关注的问题,但仍有一些问题需要避免,CSP会为您做到这一点。
为CSP测试网站的一个很好的资源是https://securityheaders.io/
您可以在http://www.html5rocks.com/en/tutorials/security/content-security-policy/
了解有关CSP的更多信息答案 14 :(得分:1)
这是 JSX 语法中基于布尔的样式:
style={{display: this.state.isShowing ? "inherit" : "none"}}
答案 15 :(得分:1)
与在css文件中编写样式相比, React的样式属性具有以下优点:
但是, React的样式属性有一些缺点-您不能
使用JS中的CSS,您可以获得样式标签的所有优点,而没有那些缺点。到今天为止,js库中有一些受欢迎且受良好支持的CSS,包括:Emotion,Styled-Components和Radium。这些库对CSS来说就像React对HTML一样。它们允许您编写CSS并在JS代码中控制CSS。
让我们比较一下我们的代码将如何样式化简单元素。我们将设置“ hello world” div的样式,使其在桌面上显示较大,而在移动设备上显示较小。
使用样式属性
return (
<div style={{fontSize:24}} className="hello-world">
Hello world
</div>
)
由于无法在style标签中进行媒体查询,因此我们必须在元素中添加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类。情感是专门考虑性能而构建的,并使用缓存。与React样式属性相比,JS中的Css将提供更好的性能。
以下是我推荐的一些最佳做法:
我应该以此方式进行所有样式设置,并且在CSS文件中完全没有指定样式吗?
我应该完全避免使用内联样式吗?
// 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>
)
}
反应编码模式由封装的组件组成-将控制组件的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>
)
答案 16 :(得分:1)
2020更新:最佳做法是使用一个库,该库已经为您完成了艰苦的工作,并且如最初接受的答案所指出的那样,当您进行切换时不会杀死您的团队在this视频中显示(仍然有用)。也只是为了了解趋势this is a very helpful chart。在对此进行了自己的研究之后,我选择将Emotion用于我的新项目,事实证明它非常灵活且可扩展。
鉴于2015年获得最高评价的答案推荐了Radium,现在它已降为维护模式。因此,添加替代列表似乎是合理的。 post停产的Radium建议使用一些库。每个链接的站点都有易于使用的示例,因此我将避免在此处复制和粘贴代码。
答案 17 :(得分:0)
有时候,我们需要为组件中的某些元素设置样式,但是如果我们必须仅显示该组件中的某个元素,或者样式是如此之少,则可以使用React js中的内联样式来代替CSS类。 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;
答案 18 :(得分:0)
绝不建议使用任何内联CSS。我们在基于JSS的项目中使用了样式化组件。它通过在组件上添加动态类名称来保护CSS覆盖。您还可以根据传递的道具添加css值。
答案 19 :(得分:0)
我更喜欢使用样式组件。它为设计提供了更好的解决方案。
<property>
<name>yarn.resourcemanager.principal</name>
<value>yarn/master.ar.com@AR.COM</value>
</property>