React Native-単純なオブジェクトと比べてStyleSheetを使用する利点は何ですか?


105

StyleSheet.create()プレーンオブジェクトを使用するメリットとは何ですか。

const styles = StyleSheet.create({
  container: {
    flex: 1
  }
}

const styles = {
  container: {
    flex: 1
  }
}

プロパティのVSCodeインテリセンスサポートを取得します。それがメリットです。
helloworld

回答:


42

ReactネイティブのStyleSheet.jsのコメントセクションから直接引用する

コード品質:

  • スタイルをレンダー関数から遠ざけることで、コードを理解しやすくなります。

  • スタイルに名前を付けることは、render関数の低レベルコンポーネントに意味を追加するための良い方法です。

パフォーマンス:

  • スタイルオブジェクトからスタイルシートを作成すると、毎回新しいスタイルオブジェクトを作成する代わりに、IDでスタイルシートを参照できます。

  • また、ブリッジを介して一度だけスタイルを送信できます。以降のすべての使用では、IDを参照します(まだ実装されていません)。

また、StyleSheetはスタイルシートのコンテンツも検証します。したがって、StyleSheetが実際に実装されている実行時ではなく、コンパイル時に、不正なスタイルプロパティのエラーが表示されます。


46
最初の3つの箇条書きは、スタイルオブジェクトをレンダリング関数の外部でconstとして宣言するOPの手法とは無関係です。
Owen Masback 2017

12
説明を読んでも、まだがどのようStyleSheet.create({styles...})に優れている/速いかわかりません{styles...}。コードも同様にクリーンで、インライン化の代わりにネーミングを使用しています。誰かがそれに光を当てることができますか?
freeall 2018年

9
StyleSheetコンパイル時に検証を提供
Jeevan Takhar

10
反対投票。回答に無関係な情報(「スタイルをレンダー機能から遠ざける」など)を含めないでください。
ロイマンソン

5
反対投票されたOPの問題は、StyleSheet.createインラインオブジェクトとクラス外のconstではなく、プレーンオブジェクトとの違いでした
quirimmo

56

メリットはありません。限目。

神話1:StyleSheetパフォーマンスが高い

StyleSheetとの外部で宣言されたオブジェクトのパフォーマンスにはまったく違いがありませんrenderrender毎回新しいオブジェクトを作成する場合は、毎回異なります)。パフォーマンスの違いは神話です。

神話の起源は、React Nativeチームがこれを行おうとしたためと考えられますが、成功しませんでした。公式ドキュメントのどこにもパフォーマンスに関する情報はありません:https : //facebook.github.io/react-native/docs/stylesheet.html、ソースコードは「まだ実装されていません」:https : //github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js#L207

神話2:StyleSheetコンパイル時にスタイルオブジェクトを検証する

本当じゃない。プレーンJavaScriptは、コンパイル時にオブジェクトを検証できません。

2つのこと:

  • 実行時に検証しますが、スタイルオブジェクトをコンポーネントに渡すときにも検証します。変わりはない。
  • FlowまたはTypeScriptを使用している場合はコンパイル時に検証しますが、オブジェクトをスタイルプロップとしてコンポーネントに渡した場合、または以下のようにオブジェクトを適切にタイプヒントした場合は検証します。違いもありません。
const containerStyle: ViewStyle = {
   ...
}

3
そうだね。おそらく、以前のバージョンのドキュメントに混乱が生じて、最終的にはスタイルがIDで参照されるようになったことを示しています。それは0.59のドキュメントでは言及されていません。
eremzeit

1
謎解きのためのTHX。しかし、質問はオープンです-何のために?
Vasiliy Vanchuk


この回答をありがとうございます。それはより多くの賛成票に値します:)
ThaJay

3
私のテストでは、それがあることを示してい例えば、コンポーネントに渡す必要がなく、実行時に検証をStyleSheet.create( {x:{flex: "1"}} )この上typescriptですチェックはコンパイル時にするように、実行時に失敗します。
グレンローレンス

24

受け入れられた回答は、OPの質問に対する回答ではありません。

問題は、インラインスタイルとconstクラスの外側の違いではなく、StyleSheet.createプレーンオブジェクトの代わりに使用する理由です。

私が見つけたものを少し調査した後、次のようになります(情報があれば更新してください)。のアドバタンジはStyleSheet.create次のとおりです。

  1. スタイルを検証します
  2. スタイルのIDへのマッピングを作成し、新しいオブジェクトを作成するたびに作成するのではなく、このIDで内部を参照するため、パフォーマンスが向上します。したがって、すべての新しいオブジェクトを毎回送信する必要がないため、デバイスを更新するプロセスでさえ高速になります。

11
これらは神話です。私の答えを確認してください。
NikolaMihajlović19年

クラスの外で(またはクラスプロパティとしても)スタイルオブジェクトを定義すると、1回(またはインスタンスごとに1回)作成されます。再度作成される同じオブジェクトは、関数内でのみ関連します。
ThaJay

はい、constですが、クラスプロパティはありません。静的クラスプロパティyep。
quirimmo

5

これは、スタイルシートを使用すると、よりパフォーマンスだったと考えられるために使用される、として 推奨バージョン0.57までRNチームアップにより、このような理由のために、しかし正確に指摘したように、それはもはや推奨されていない別の答えこの質問へ。

RNのドキュメントでは、私はこれらの理由は、レンダリング機能の外に作成されたプレーンなオブジェクトにも同様に適用と思いますけれども、今、次のような理由でスタイルシートをお勧めします。

  • スタイルをレンダー関数から遠ざけることで、コードを理解しやすくなります。
  • スタイルに名前を付けることは、render関数の低レベルコンポーネントに意味を追加するための良い方法です。

だから私は何だと思いますされているプレーンなオブジェクトの上にスタイルシートを使用しての可能な利点は?

1)反対の主張にもかかわらず、RN v0.59.10での私のテストは、呼び出し時に検証が行われStyleSheet.create()、typescript(およびおそらくフロー)もコンパイル時にエラーを報告することを示しています。コンパイル時のチェックがなくても、レンダリングに使用するに、特にそれらのスタイルを使用するコンポーネントが条件付きでレンダリングされる可能性がある場合は、実行時にスタイルの検証を行うことが有益だと思います。これにより、すべてのレンダリングシナリオをテストしなくても、そのようなエラーを検出できます。

2)RNチームがStyleSheet 推奨していることを考えると、StyleSheet を使用して将来のパフォーマンスを改善することを望んでいる可能性があり、次のような他の改善も考えられます。

3)現在のStyleSheet.create()ランタイム検証は有用ですが、少し制限があります。これは、フローまたはタイプスクリプトで取得するタイプチェックに制限されているようです。そのため、「」flex: "1"または「」を取得しますが、パーセント文字列ではborderStyle: "rubbish"ないwidth: "rubbish"可能性があります。RNチームは、パーセンテージ文字列や範囲の制限などをチェックすることで、今後このような検証を改善する可能性があります。またはStyleSheet.create()、独自の関数をラップして、より広範な検証を行うことができます。

4)StyleSheetを使用すると、react-native-extended-stylesheetのようなサードパーティの代替/拡張機能への移行が容易になります。


1

経由でスタイルを作成するStyleSheet.createと、グローバル変数__DEV__がtrueに設定されている場合にのみ検証が通過します(またはAndroidまたはIOSエミュレーター内で実行しているときにReact Native DEVおよびPROD変数を参照)

関数のソースコードは非常に単純です。

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;
}

開発時にランタイム検証を実行し、オブジェクトをフリーズするため、これを使用することをお勧めします。


0

StyleSheetTypeScriptでの入力検証を除いて、between とplainオブジェクトの違いは見つかりませんでした。

たとえば、これ(タイプの違いに注意してください):

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,
  },
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.