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 中动态样式的最高效方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

react-native怎么动态改变样式

UITableView:创建索引的最高效方式?

Text Rendering iOS - 渲染快速变化文本的最高效方式

转换/移动大量 DOM 元素的最高效方式

在 Flutter 和 Dart 中重构小部件的最优雅/高效的方式

react-native-pg-style使用方法(以最简单的方式编写样式代码)