【问题标题】:The purpose of StyleSheet.create in React NativeReact Native 中 StyleSheet.create 的用途
【发布时间】:2019-12-06 11:34:35
【问题描述】:

我想向社区询问有关 React Native 中 StyleSheet.create 的变化。

之前:

我已经回顾了过去有关此主题的问题,例如this question,但它们都在很久以前得到了回答(除了this answer,但我想有一些明确的东西)并且很多都发生了变化自从。

在 StyleSheet 为样式创建唯一 ID 之前,主要用于性能优化。如果您想从创建的样式对象中获取样式,您应该使用flatten 方法。大多数答案都引用了这种 flatten 方法,并且您无法像访问普通对象一样访问样式属性。

例如

const styles = StyleSheet.create({
  modalContainer: {
    width: 100,
    backgroundColor: 'white',
    padding: 5,
  },

你可以访问像styles.modalContainer.padding;这样的填充样式

目前:

但是,它的行为已经改变。 This is the source code of StyleSheet 来自 React Native 团队。只是复制create方法:

create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
    // 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;
  },
};

这只是返回传递给 create 的对象,而不对其进行任何操作。所以您可以styles.modalContainer.padding;

的身份实际访问样式

也许我对 TODO 的理解不是很清楚,但是这种方法至少从 RN 0.57 开始就是这样编码的,我不知道他们是否会改回来。

我的问题:

再使用StyleSheet.create还有意义吗?

提前感谢您分享您的意见!

【问题讨论】:

  • 为了验证和代码拆分,我认为值得使用!

标签: react-native


【解决方案1】:

样式表通常用于在 react native 中创建全局样式,并将其添加到需要设置对象样式的相应视图中。

TextInput、Text、Button 等一些小部件无法应用 react native 中几乎所有的 css 样式。

因此,在这些情况下,您可以使用 StyleSheet.create() 方法包装这些小部件,然后可以创建全局样式表以全局使用并减少您的头痛。

因此,您的问题的结论可以总结为 Stylesheet.create() 有助于提高性能,而使用相同样式设置多个视图的样式将每次为每个视图创建一个新对象。

而 Stylesheet.create() 将充当所有视图的单个全局对象,所有视图都使用它来设置自己的样式,从而实现性能/内存优化。

【讨论】:

  • 如果我正确理解了您的答案,您不会通过简单地全局定义样式对象而不是在每个组件上内联来获得相同的“性能/内存优化”改进吗?也就是说,不是const styles = StyleSheet.create({ ... }),而是const styles = { ... }
  • 您将获得更好的性能优化。但是,您需要为所有项目元素持续定义相同的样式。这将导致您增加大量工作。毕竟,即使是您的中级项目也需要为这么多组件进行大量样式设置。无论如何选择是你的。
  • @JayMungara 根据 Adam 的评论,您不需要“不断定义相同的样式......”,因为我认为 Adam 意味着通过导出样式然后导入其他文件来重用样式。
【解决方案2】:

我从来没有听说过这个flatten() 像你描述的那样是必要的。事实上,在第一次提交的 React Native 存储库中,提供了一个示例:

示例/电影/MovieCell.js:

https://github.com/facebook/react-native/commit/a15603d8f1ecdd673d80be318293cee53eb4475d#diff-4712aeb2165b3c0ce812bef903be3464

在此示例中,您可以看到 var styles = StyleSheet.create({..}); 以其当前风格使用,而在 2016 年的那一刻,您可以看到组件中引用的样式为 styles.styleName

另外,这里的 StyleSheet 类中还有来自初始提交的 create

class StyleSheet {
   static create(obj) {
     var result = {};
     for (var key in obj) {
       StyleSheet.validateStyle(key, obj);
       result[key] = StyleSheetRegistry.registerStyle(obj[key]);
     }
     return result;
   }
// ...
}

如您所见,在初始提交时没有调用flatten,既不是在create 方法内,也不是来自使用create 的用户。

总而言之,这似乎从未改变,您始终可以使用点运算符访问样式。

至于是否使用它,我认为您别无选择。它里面显然有某种验证代码,它也使用类型检查,react 团队建议使用它。我没有看到任何其他方法可以做到这一点。你怎么能在没有创建的情况下使用类,只使用某种初始化或构造方法?我在课堂上没有看到一个。没有StyleSheet({...}); 要返回obj,您需要调用create

如果您剥离验证行为并使其成为普通对象,您的编辑器将无法为您提供 IntelliSense。你不会知道你什么时候打错字或引用不存在的样式,你不会有自动完成功能。您需要创建自己的界面并使用 TypeScript。因此你应该使用create,否则至少你会破坏你的IDE。

【讨论】:

    猜你喜欢
    • 2017-07-19
    • 2021-12-29
    • 2020-09-02
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多