React Native - 使用 StyleSheet 与普通对象相比有什么好处?
React Native - What is the benefit of using StyleSheet vs a plain object?
与普通对象相比,使用 StyleSheet.create()
到底有什么好处?
const styles = StyleSheet.create({
container: {
flex: 1
}
}
比
const styles = {
container: {
flex: 1
}
}
直接引用 React nativeStyleSheet.js 的评论部分
Code quality:
By moving styles away from the render function, you're making the code easier to understand.
Naming the styles is a good way to add meaning to the low level components in the render function.
Performance:
Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.
It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).
StyleSheet 还会验证您的样式表内容。因此,任何不正确样式的错误 属性 都会在编译时显示,而不是在实际实现 StyleSheet 时在运行时显示。
接受的答案不是 OP 问题的答案。
问题不是内联样式和 class 之外的 const
之间的区别,而是为什么我们应该使用 StyleSheet.create
而不是普通对象。
经过一番研究,我发现了以下内容(如果您有任何信息,请更新)。
StyleSheet.create
的优点应该是:
- 它验证样式
- 更好的性能,因为它创建了样式到 ID 的映射,然后使用此 ID 在内部引用,而不是每次都创建一个新对象。因此,即使更新设备的过程也更快,因为您不会每次都发送所有新对象。
没有任何好处。期间.
误区 1:StyleSheet
性能更高
StyleSheet
和在 render
外声明的对象之间绝对没有性能差异(如果你每次都在 render
内创建一个新对象,情况会有所不同) .性能差异是一个神话。
这个神话的起源很可能是因为 React Native 团队试图这样做,但他们没有成功。在官方文档中您找不到任何有关性能的信息:https://facebook.github.io/react-native/docs/stylesheet.html, while source code states "not implemented yet": https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js#L207
误区 2:StyleSheet
在编译时验证样式对象
这不是真的。 Plain JavaScript 无法在编译时验证对象。
两件事:
- 它确实在运行时验证,但当您将样式对象传递给组件时也是如此。没有区别。
- 如果您使用的是 Flow 或 TypeScript,它会在编译时验证 ,但是一旦您将对象作为样式道具传递给组件,或者如果您正确地如下所示的类型提示对象。也没有区别。
const containerStyle: ViewStyle = {
...
}
以前认为使用 StyleSheet 性能更高, recommended for this reason by the RN team up until version 0.57, but it is now no longer recommended as correctly pointed out in 这个问题。
RN documentation 现在推荐 StyleSheet 的原因如下,尽管我认为这些原因同样适用于在渲染函数之外创建的普通对象:
- 通过将样式从渲染函数中移开,您可以
代码更容易理解。
- 给样式命名是给底层增加意义的好方法
渲染函数中的组件。
那么我认为 使用 StyleSheet 相对于普通对象的可能好处是什么?
1) 尽管有相反的说法,但我在 RN v0.59.10 上的测试表明您 do 在调用 StyleSheet.create()
和打字稿(可能是流程)时得到了一些验证编译时也会报错。即使没有编译时检查,我认为在 运行 样式 用于渲染之前 时间验证仍然是有益的,特别是在可以有条件地渲染使用这些样式的组件的情况下。这将允许拾取此类错误,而无需测试所有渲染方案。
2) 鉴于 RN 团队推荐的 StyleSheet 是 他们可能仍然希望将来使用 StyleSheet 来提高性能,并且他们可能会考虑其他可能的改进,因为嗯,例如:
3) 当前的 StyleSheet.create()
运行 时间验证很有用,但有点受限。它似乎仅限于使用 flow 或 typescript 进行的类型检查,因此会选择 flex: "1"
或 borderStyle: "rubbish"
,但不会选择 width: "rubbish"
,因为它可能是百分比字符串。 RN 团队将来可能会通过检查百分比字符串或范围限制等内容来改进此类验证,或者您可以将 StyleSheet.create()
包装在您自己的函数中以进行更广泛的验证。
4) 通过使用 StyleSheet,您可能可以更轻松地过渡到提供更多服务的第三方 alternatives/extensions,例如 react-native-extended-stylesheet。
我没有发现 StyleSheet
和普通对象之间有任何区别,除了 TypeScript 中的输入验证。
例如,这个(注意打字差异):
import { View, Text, Image, StyleSheet } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: StyleSheet.create({
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
});
等于:
import { View, Text, Image, ViewStyle, TextStyle, ImageStyle } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: {
someViewStyle: ViewStyle;
someTextStyle: TextStyle;
someImageStyle: ImageStyle;
} = {
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
};
只有当全局变量 __DEV__
设置为 true 时(或者当 运行ning 在 Android 或 [=24 中时,通过 StyleSheet.create
创建样式才会通过验证=] 模拟器见 )
函数source代码很简单:
create < +S: ____Styles_Internal > (obj: S): $ReadOnly < S > {
// TODO: This should return S as the return type. But first,
// we need to codemod all the callsites that are typing this
// return value as a number (even though it was opaque).
if (__DEV__) {
for (const key in obj) {
StyleSheetValidation.validateStyle(key, obj);
if (obj[key]) {
Object.freeze(obj[key]);
}
}
}
return obj;
}
我会推荐使用它,因为它在开发过程中执行 运行 次验证,它还会冻结对象。
所以,今天,2021 年 9 月,在阅读了所有答案并进行了一些研究之后,我创建了一个关于使用 Stylesheet
而不是普通对象的摘要。
- 基于React Documentation,当复杂性开始增加时,您应该使用样式表。
The style prop can be a plain old JavaScript object. That's what we usually use for example code.
As a component grows in complexity, it is often cleaner to use StyleSheet.create to define several styles in one place.
- 在模拟器中,使用stylesheet时会显示ERROR,而使用plain object时只会显示WARNING。
- 根据第 2 项,看起来它在编译时进行了一些验证。 (很多人说那是神话)
- 如果你以后需要迁移第三方库,比如
react-native-extended-stylesheet
,如果你使用样式表,那就更容易了。
- 你有一些 methods and properties 可以促进发展。例如,属性
StyleSheet.absoluteFill
将执行 position: 'absolute', left: 0, right: 0, top: 0, bottom: 0
,或者方法 compose()
将允许您组合两种样式,覆盖它。
P.S.: 性能答案看起来是个神话。
我的意见?
根据第 2 项和第 5 项,转到样式表而不是普通对象。
与普通对象相比,使用 StyleSheet.create()
到底有什么好处?
const styles = StyleSheet.create({
container: {
flex: 1
}
}
比
const styles = {
container: {
flex: 1
}
}
直接引用 React nativeStyleSheet.js 的评论部分
Code quality:
By moving styles away from the render function, you're making the code easier to understand.
Naming the styles is a good way to add meaning to the low level components in the render function.
Performance:
Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.
It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).
StyleSheet 还会验证您的样式表内容。因此,任何不正确样式的错误 属性 都会在编译时显示,而不是在实际实现 StyleSheet 时在运行时显示。
接受的答案不是 OP 问题的答案。
问题不是内联样式和 class 之外的 const
之间的区别,而是为什么我们应该使用 StyleSheet.create
而不是普通对象。
经过一番研究,我发现了以下内容(如果您有任何信息,请更新)。
StyleSheet.create
的优点应该是:
- 它验证样式
- 更好的性能,因为它创建了样式到 ID 的映射,然后使用此 ID 在内部引用,而不是每次都创建一个新对象。因此,即使更新设备的过程也更快,因为您不会每次都发送所有新对象。
没有任何好处。期间.
误区 1:StyleSheet
性能更高
StyleSheet
和在 render
外声明的对象之间绝对没有性能差异(如果你每次都在 render
内创建一个新对象,情况会有所不同) .性能差异是一个神话。
这个神话的起源很可能是因为 React Native 团队试图这样做,但他们没有成功。在官方文档中您找不到任何有关性能的信息:https://facebook.github.io/react-native/docs/stylesheet.html, while source code states "not implemented yet": https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js#L207
误区 2:StyleSheet
在编译时验证样式对象
这不是真的。 Plain JavaScript 无法在编译时验证对象。
两件事:
- 它确实在运行时验证,但当您将样式对象传递给组件时也是如此。没有区别。
- 如果您使用的是 Flow 或 TypeScript,它会在编译时验证 ,但是一旦您将对象作为样式道具传递给组件,或者如果您正确地如下所示的类型提示对象。也没有区别。
const containerStyle: ViewStyle = {
...
}
以前认为使用 StyleSheet 性能更高, recommended for this reason by the RN team up until version 0.57, but it is now no longer recommended as correctly pointed out in
RN documentation 现在推荐 StyleSheet 的原因如下,尽管我认为这些原因同样适用于在渲染函数之外创建的普通对象:
- 通过将样式从渲染函数中移开,您可以 代码更容易理解。
- 给样式命名是给底层增加意义的好方法 渲染函数中的组件。
那么我认为 使用 StyleSheet 相对于普通对象的可能好处是什么?
1) 尽管有相反的说法,但我在 RN v0.59.10 上的测试表明您 do 在调用 StyleSheet.create()
和打字稿(可能是流程)时得到了一些验证编译时也会报错。即使没有编译时检查,我认为在 运行 样式 用于渲染之前 时间验证仍然是有益的,特别是在可以有条件地渲染使用这些样式的组件的情况下。这将允许拾取此类错误,而无需测试所有渲染方案。
2) 鉴于 RN 团队推荐的 StyleSheet 是 他们可能仍然希望将来使用 StyleSheet 来提高性能,并且他们可能会考虑其他可能的改进,因为嗯,例如:
3) 当前的 StyleSheet.create()
运行 时间验证很有用,但有点受限。它似乎仅限于使用 flow 或 typescript 进行的类型检查,因此会选择 flex: "1"
或 borderStyle: "rubbish"
,但不会选择 width: "rubbish"
,因为它可能是百分比字符串。 RN 团队将来可能会通过检查百分比字符串或范围限制等内容来改进此类验证,或者您可以将 StyleSheet.create()
包装在您自己的函数中以进行更广泛的验证。
4) 通过使用 StyleSheet,您可能可以更轻松地过渡到提供更多服务的第三方 alternatives/extensions,例如 react-native-extended-stylesheet。
我没有发现 StyleSheet
和普通对象之间有任何区别,除了 TypeScript 中的输入验证。
例如,这个(注意打字差异):
import { View, Text, Image, StyleSheet } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: StyleSheet.create({
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
});
等于:
import { View, Text, Image, ViewStyle, TextStyle, ImageStyle } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: {
someViewStyle: ViewStyle;
someTextStyle: TextStyle;
someImageStyle: ImageStyle;
} = {
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
};
只有当全局变量 __DEV__
设置为 true 时(或者当 运行ning 在 Android 或 [=24 中时,通过 StyleSheet.create
创建样式才会通过验证=] 模拟器见
函数source代码很简单:
create < +S: ____Styles_Internal > (obj: S): $ReadOnly < S > {
// TODO: This should return S as the return type. But first,
// we need to codemod all the callsites that are typing this
// return value as a number (even though it was opaque).
if (__DEV__) {
for (const key in obj) {
StyleSheetValidation.validateStyle(key, obj);
if (obj[key]) {
Object.freeze(obj[key]);
}
}
}
return obj;
}
我会推荐使用它,因为它在开发过程中执行 运行 次验证,它还会冻结对象。
所以,今天,2021 年 9 月,在阅读了所有答案并进行了一些研究之后,我创建了一个关于使用 Stylesheet
而不是普通对象的摘要。
- 基于React Documentation,当复杂性开始增加时,您应该使用样式表。
The style prop can be a plain old JavaScript object. That's what we usually use for example code. As a component grows in complexity, it is often cleaner to use StyleSheet.create to define several styles in one place.
- 在模拟器中,使用stylesheet时会显示ERROR,而使用plain object时只会显示WARNING。
- 根据第 2 项,看起来它在编译时进行了一些验证。 (很多人说那是神话)
- 如果你以后需要迁移第三方库,比如
react-native-extended-stylesheet
,如果你使用样式表,那就更容易了。 - 你有一些 methods and properties 可以促进发展。例如,属性
StyleSheet.absoluteFill
将执行position: 'absolute', left: 0, right: 0, top: 0, bottom: 0
,或者方法compose()
将允许您组合两种样式,覆盖它。
P.S.: 性能答案看起来是个神话。
我的意见?
根据第 2 项和第 5 项,转到样式表而不是普通对象。