React-Native 中动态样式的最高效方式是啥?
Posted
技术标签:
【中文标题】React-Native 中动态样式的最高效方式是啥?【英文标题】:What is the most performant way for dynamic styling in React-Native?React-Native 中动态样式的最高效方式是什么? 【发布时间】:2019-01-11 11:24:33 【问题描述】:
在 React-Native 中,您可以使用 Stylesheet 创建类似 css 的样式表。使用 styleshee.create
来支持普通 js-objects 的主要原因是提高了性能。但是,您通常可能希望动态地设置组件的样式,通常基于它们的 props。我基本上找到了三种方法:
以下示例的注意事项: 考虑在组件外部声明 const styles ...
,因为它是一种常见模式,您可能希望在不同组件之间共享样式.将树点下方的所有内容视为渲染函数的一部分。
使用样式数组:
const styles = StyleSheet.create(viewStyle: backgroundColor:'red')
...
return <View style=[styles.viewStyle, color: this.props.color] />
使用 Stylesheet.flatten:
const styles = StyleSheet.create(viewStyle: backgroundColor:'red')
...
const flattenedStyle = StyleSheet.flatten(styles.viewStyle, color: this.props.color)
return <View style=flattenedStyle />
使用函数创建样式表:
const styles = (color) => StyleSheet.create(
viewStyle:
backgroundColor:'red',
color: color
)
...
const style = styles(this.props.color).viewStyle
return <View style=style />
我想知道哪种方法在性能方面最好,或者是否还有另一种性能更高的方法?我认为选项 2 和 3 根本不可能,因为在 prop-changes 上动态创建新样式表破坏了样式表的全部目的。对于这个主题的任何想法或提示,我都很高兴!
【问题讨论】:
你找到答案了吗? 很遗憾没有。在大多数情况下,我只使用方法 1。 我也认为选项 2 和 3 会花费时间,并且会使您的代码比平时快 5 倍,因此我建议使用选项 1,因为它简单、干净且易于编写 1000 次! 【参考方案1】:在这里你可以为每个样式在 react native 中做动态样式。
这样
<Text style=styles.simpleText('red')>Required field</Text>
// In styling
const styles = StyleSheet.create(
simpleText: (colorProp = 'black') => ( // default black set
fontSize: 14,
color: colorProp,
)
)
您还可以传递任何数据类型以进行条件样式
【讨论】:
【参考方案2】:一种方法
// homeSreen
<View style=styles.filterButton(isSelected)>
<Text> Strawberry </Text>
</View>
// styles.js
import StyleSheet from 'react-native';
import Colors from '../../theme';
export default StyleSheet.create(
container:
backgroundColor: Colors.lighter,
,
filterButton: isSelected => (
padding: 15,
backgroundColor: isSelected? Colors.background.primary: Colors.background.secondary
),
);
【讨论】:
【参考方案3】:您可以使用 React 钩子来记忆样式表的创建,但首先您需要进行一些性能检查,以确定样式表的创建是否实际上是一个值得优化的 CPU 和/或内存消耗。
这是一个例子:
const styles = (color) => StyleSheet.create(
viewStyle:
backgroundColor:'red',
color: color
)
/*
even though makeStyle is defined in EVERY render,
React will only run it ONCE for any given props.color distinct value.
The resulting value `styles` survives re-renders
*/
const makeStyle = () => styles(props.color)
const styles = useMemo(makeStyle, [props.color]);
这是official documentation。
【讨论】:
当前StyleSheet.create
的实现速度非常快,useMemo
还可以。问题是值得使用记忆化(不是纯子组件),或者您可以在每次渲染时创建新对象。【参考方案4】:
您是否考虑过 Styled components
等 JS 库中的 CSS?
您可以传递道具并获得动态样式:
https://styled-components.com/docs/basics#passed-props
【讨论】:
难以想象如此复杂的库会提供最佳性能。最好的开发者体验,当然,但这不是问题。【参考方案5】:对于简单的动态样式可能有点矫枉过正,但 Reanimated 的性能非常好,并且会以 60fps https://github.com/software-mansion/react-native-reanimated 运行样式转换
它通过提前声明动画/过渡所需的所有样式来存档,并在本机线程上运行它们,因此跨 JS->本机代码桥的通信最少。
在他们的关于页面上有更好的解释https://docs.swmansion.com/react-native-reanimated/docs/about
【讨论】:
以上是关于React-Native 中动态样式的最高效方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Text Rendering iOS - 渲染快速变化文本的最高效方式