web-dev-qa-db-ja.com

React.jsインラインスタイルのベストプラクティス

このように、Reactクラス内でスタイルを指定できることを私は知っています:

var MyDiv = React.createClass({
  render: function() {
    var style = {
      color: 'white',
      fontSize: 200
    };

    return <div style={style}> Have a good and productive day! </div>;
  }
});

私はこのようにしてすべてのスタイルを設定し、CSSファイルにスタイルをまったく指定しないようにする必要がありますか。

それとも、インラインスタイルを完全に避けるべきですか?

両方を少し行うのは変で面倒なようです - スタイルを微調整するときは2か所をチェックする必要があります。 

415
eye_mew

まだ多くの「ベストプラクティス」はありません。 Reactコンポーネントのためにインラインスタイルを使用している私たちはまだまだ実験的です。

大きく異なるアプローチがいくつかあります。 インラインスタイルのlib比較チャートを反応させる

全部かゼロか?

「スタイル」と呼ぶものには、実際にはかなりの数の概念が含まれています。

  • レイアウト - 要素/コンポーネントが他の要素との関係でどのように見えるか
  • 外観 - 要素/コンポーネントの特性
  • 振る舞いと状態 - 与えられた状態で要素/コンポーネントがどのように見えるか

状態スタイルから始める

Reactはすでにあなたのコンポーネントの状態を管理しています、これは stateとbehavior のスタイルをあなたのコンポーネントロジックとのコロケーションに自然に合うようにします。

条件付き状態クラスでレンダリングするコンポーネントを構築する代わりに、状態スタイルを直接追加することを検討してください。

// Typical component with state-classes
<li 
 className={classnames({ 'todo-list__item': true, 'is-complete': item.complete })} />


// Using inline-styles for state
<li className='todo-list__item'
 style={(item.complete) ? styles.complete : {}} />

appearance をスタイルするためにクラスを使用していますが、 stateおよび動作 に接頭辞.is-クラスは使用していません。

Object.assign(ES6)または_.extend(下線/下線)を使用して、複数の状態のサポートを追加できます。

// Supporting multiple-states with inline-styles
<li 'todo-list__item'
 style={Object.assign({}, item.complete && styles.complete, item.due && styles.due )}>

カスタマイズと再利用

Object.assignを使用しているので、コンポーネントをさまざまなスタイルで再利用できるようにするのは非常に簡単になります。デフォルトのスタイルを上書きしたい場合は、<TodoItem dueStyle={ fontWeight: "bold" } />のように、コールサイトで小道具を使って変更できます。このように実装されています:

<li 'todo-list__item'
 style={Object.assign({},
         item.due && styles.due,
         item.due && this.props.dueStyles)}>

レイアウト

個人的には、私はレイアウトスタイルをインライン化する説得力のある理由を見ません。そこにはたくさんの素晴らしいCSSレイアウトシステムがあります。私はただそれを使います。

そうは言っても、コンポーネントにレイアウトスタイルを直接追加しないでください。コンポーネントをレイアウトコンポーネントで囲みます。これが一例です。

// This couples your component to the layout system
// It reduces the reusability of your component
<UserBadge
 className="col-xs-12 col-sm-6 col-md-8"
 firstName="Michael"
 lastName="Chan" />

// This is much easier to maintain and change
<div class="col-xs-12 col-sm-6 col-md-8">
  <UserBadge
   firstName="Michael"
   lastName="Chan" />
</div>

レイアウトをサポートするために、私はコンポーネントを100%width、およびheightになるように設計することがよくあります。

外観

これは「インラインスタイル」の議論の中で最も論争の的になっている分野です。最終的には、それはあなたがデザインしたコンポーネントとJavaScriptを使ったあなたのチームの快適さ次第です。

一つ確かなことは、図書館の援助が必要だということです。ブラウザ状態(:hover:focus)、およびメディアクエリは生のReactでは苦痛です。

私は Radium が好きです。なぜなら、これらの難しい部分の構文はSASSのそれをモデル化するように設計されているからです。

コード編成

多くの場合、モジュールの外側にスタイルオブジェクトがあります。 ToDoリストコンポーネントの場合は、次のようになります。

var styles = {
  root: {
    display: "block"
  },
  item: {
    color: "black"

    complete: {
      textDecoration: "line-through"
    },

    due: {
      color: "red"
    }
  },
}

ゲッター関数

あなたのテンプレートにたくさんのスタイルロジックを追加することは(上で見たように)少し面倒になるかもしれません。スタイルを計算するための取得関数を作成するのが好きです。

React.createClass({
  getStyles: function () {
    return Object.assign(
      {},
      item.props.complete && styles.complete,
      item.props.due && styles.due,
      item.props.due && this.props.dueStyles
    );
  },

  render: function () {
    return <li style={this.getStyles()}>{this.props.item}</li>
  }
});

さらに見る

私は今年の初めにReact Europeでこれらすべてをより詳細に議論しました: インラインスタイルと 'CSSを使うだけの場合'

あなたがその過程で新しい発見をするとき私は助けてうれしいです:)私を襲ってください - > @chantastic

417
chantastic

Reactのstyle属性は値がオブジェクト、すなわちキーと値のペアであることを期待します。

style = {}はそれを機能させるために{float:'right'}のような内部に別のオブジェクトを持ちます。

<span style={{float:'right'}}>{'Download Audit'}</span>

これで問題が解決することを願っています

90
anandharshan

私は私のReactコンポーネントの中で広くインラインスタイルを使っています。コンポーネント内にスタイルを配置する方がはるかに明確であることがわかります。これは、コンポーネントにどんなスタイルがあるのか​​、ないのかが常に明らかだからです。さらに、Javascriptの全機能を手元に持っていることで、より複雑なスタイル設定のニーズも簡単になります。

私は最初は納得できませんでしたが、数ヶ月間手を加えた後、私は完全に変換し、すべてのCSSをインラインまたは他のJS駆動のcssメソッドに変換する過程にあります。

Facebookの従業員とReactの寄稿者 "vjeux"によるこのプレゼンテーションも同様に本当に役に立ちます - https://speakerdeck.com/vjeux/react-css-in-js

45
Kyle Mathews

Style属性の主な目的は、動的な状態ベースのスタイルです。たとえば、何らかの状態に基づいてプログレスバーに幅スタイルを設定したり、他の状態に基づいて位置や表示設定を表示したりできます。

JSのスタイルには、アプリケーションが再利用可能なコンポーネントのカスタムスタイルを提供できないという制限があります。これは前述の状況では完全に受け入れられますが、視覚的な特性、特に色を変更するときには不可能です。

21
FakeRainBrigand

James K Nelson氏の手紙の中で "なぜJavaScriptでコンポーネントのスタイルを変えるべきではないのか" は、その欠点のためにインラインスタイルを使う必要は実際にはないと述べています。彼の発言は、less/scssの古い退屈なcssが最善の解決策であるということです。彼の論文の一部はcssを支持しています:

  • 外部から拡張可能
  • leverable(インラインスタイルはすべてを凌駕する)
  • デザイナー向け
16
alex_1948511

再利用可能な各コンポーネントに一意のカスタム要素名を付けてから、そのコンポーネントのCSSファイルを作成します。具体的には、そのコンポーネントのすべてのスタイル設定オプションを使用します(そのコンポーネントのみ)。 

var MyDiv = React.createClass({
  render: function() {
    return <custom-component style={style}> Have a good and productive day! </custom-component>;
  }
});

そして 'custom-component.css'ファイルでは、すべてのエントリはcustom-componentタグで始まります。

custom-component { 
   display: block; /* have it work as a div */
   color: 'white'; 
   fontSize: 200; 
} 
custom-component h1 { 
  font-size: 1.4em; 
}

それはあなたが懸念を切り離すという批判的な概念を失うことがないということです。スタイル対ビュー。あなたがあなたのコンポーネントを共有する場合、他の人が自分のWebページの他の部分と一致するようにそれをテーマにする方が簡単です。

6
widged

それは本当にbigあなたのアプリケーションがwebpackのようなバンドルを使いたいのなら、あなたのアプリケーションがどのようにビルドにCSSとJSをバンドルしたいのか、そしてあなたはあなたのアプリケーションフローをどう管理したいのか!あなたの状況では、あなたは決断を下すことができます!

大きなプロジェクトでファイルを整理するのが私の好みはCSSとJSファイルを分けることです。共有するのが簡単で、UIファイルをCSSのファイルに通すのが簡単になるでしょう。

常にこのように考え、開発段階ではすべてが適切な名前であり、他の開発者が見つけやすい場所にあることを確認してください。

私は個人的に私の必要性に応じてそれらを混ぜ合わせます、例えば... 外部のcssを使うようにしてください、しかし必要ならReactは同様にスタイルを受け入れます以下:

import React from 'react';

const App = props => {
  return (
    <div className="app" style={{background: 'red', color: 'white'}}>  /*<<<<look at style here*/
      Hello World...
    </div>
  )
}

export default App;
3
Alireza

設定によっては、インラインスタイリングによってホットリロードが可能になります。 Webページはスタイルが変わるたびに即座に再レンダリングされます。これは私がより早くコンポーネントを開発するのを助けます。そうは言っても、CSS + SCSS用のホットリロード環境を設定できると確信しています。

2
Guy

私は通常、各Reactコンポーネントに関連付けられたscssファイルを持っています。しかし、コンポーネントをロジックでカプセル化して調べないのには理由がありません。つまり、Webコンポーネントについても同じことが言えます。

2
dakt

あなたもStrCSSを使うことができます、それは孤立したクラス名ともっと多くを作成します!サンプルコードは次のようになります。構文強調表示をサポートするために、(オプション)Visual Studio MarketplaceからVSCode拡張機能をインストールできます。

ソース: https://github.com/jeffreylanters/strcss

import { Sheet } from "strcss";
import React, { Component } from "react";

const sheet = new Sheet(`
  map button
    color green
    color red !ios
    fontSize 16
  on hover
    opacity .5
  at mobile
    fontSize 10
`);

export class User extends Component {
  render() {
    return <div className={sheet.map.button}>
      {"Look mom, I'm green!
      Unless you're on iOS..."}
    </div>;
  }
}
1
Jeffrey Lanters

一部のコンポーネントでは、インラインスタイルを使用する方が簡単です。また、(CSSではなくJavascriptを使用しているため)コンポーネントスタイルをアニメートする方が簡単かつ簡潔です。

スタンドアロンコンポーネントの場合は、 'Spread Operator'または '...'を使用します。私にとっては、それは澄んでいて美しい、そして狭い空間で働いています。これが私がそれが利点であることを示すために作った小さなローディングアニメーションです: 

<div style={{...this.styles.container, ...this.state.opacity}}>
    <div style={{...this.state.colors[0], ...this.styles.block}}/>
    <div style={{...this.state.colors[1], ...this.styles.block}}/>
    <div style={{...this.state.colors[2], ...this.styles.block}}/>
    <div style={{...this.state.colors[7], ...this.styles.block}}/>
    <div style={{...this.styles.block}}/>
    <div style={{...this.state.colors[3], ...this.styles.block}}/>
    <div style={{...this.state.colors[6], ...this.styles.block}}/>
    <div style={{...this.state.colors[5], ...this.styles.block}}/>
    <div style={{...this.state.colors[4], ...this.styles.block}}/>
  </div>

    this.styles = {
  container: {
    'display': 'flex',
    'flexDirection': 'row',
    'justifyContent': 'center',
    'alignItems': 'center',
    'flexWrap': 'wrap',
    'width': 21,
    'height': 21,
    'borderRadius': '50%'
  },
  block: {
    'width': 7,
    'height': 7,
    'borderRadius': '50%',
  }
}
this.state = {
  colors: [
    { backgroundColor: 'red'},
    { backgroundColor: 'blue'},
    { backgroundColor: 'yellow'},
    { backgroundColor: 'green'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
  ],
  opacity: {
    'opacity': 0
  }
}

それから、componentWillMount()で、そのような間隔を設定します。

this.interval = setInterval(() => {
  let colors = this.state.colors;
  let opacity = this.state.opacity;

  if(this.props.reverse) {
    let color = colors[colors.length-1];
    colors.pop();
    colors.unshift(color)
  } else {
    let color = colors[0];
    colors.shift();
    colors.Push(color);
  }

  opacity['opacity'] < 1 ? opacity['opacity']+=0.06 : null;

  this.setState({colors, opacity});
}, this.speed);
1
VocoJax

インラインスタイルの問題は、コンテンツセキュリティポリシー(CSP)が一般的になりつつあり、それが許可されていないことです。したがって、インラインスタイルを完全に避けることをお勧めします。

更新: さらに説明すると、CSPはサーバーによって送信されるHTTPヘッダーで、ページに表示できるコンテンツを制限します。開発者がサイトのコードを不適切にコーディングした場合、攻撃者が悪意のあることをするのを防ぐために、サーバーに適用される可能性のあるさらなる緩和策です。

これらの制限の大部分の目的は、XSS(クロスサイトスクリプティング)攻撃を阻止することです。 XSSは、攻撃者が自分のjavascriptをあなたのページに含める方法を見つけ出す場所です(たとえば、私が自分のユーザ名をbob<SCRIPT>alert("hello")</SCRIPT>にしてからコメントを投稿し、そのページにアクセスしても警告は表示されない)。開発者はユーザーにこのようなコンテンツをサイトに追加させることはできませんが、万が一のためにscript>タグが見つかった場合、CSPはそのページの読み込みをブロックします。

CSPは、開発者が間違いを犯した場合、攻撃者がそのサイトの訪問者に問題を引き起こすことはないということを保証するための単なる保護レベルです。

すべてがXSSですが、攻撃者が<script>タグを含めることはできませんが、<style>タグを含めることができる場合、またはタグにstyle=パラメータを含めることができる場合はどうなりますか?それから彼はあなたが間違ったボタンをクリックすることに騙されるか、または他の問題のようにサイトの外観を変えることができるかもしれません。これはそれほど心配する必要はありませんが、やはり避けるべきことであり、CSPはあなたに代わってそれを行います。

CSPのためのサイトをテストするための良いリソースは https://securityheaders.io/ /です。

あなたはCSPについてもっと読むことができます: http://www.html5rocks.com/en/tutorials/security/content-security-policy/

1
0xdabbad00

これは、 _ jsx _ 構文のブール値ベースのスタイルです。

style={{display: this.state.isShowing ? "inherit" : "none"}}
1
Anupam Maurya

インラインスタイルを使用できますが、すべてのスタイルでそれらを使用している場合はいくつかの制限があります。いくつかの既知の制限は使用できません CSS疑似セレクタ および メディアクエリ inそこ。

これを解決するために Radium https://github.com/FormidableLabs/radium を使うことができますが、それでもやはり、プロジェクトがその厄介なものになると思います。

CSSモジュールを使うことをお勧めします https://github.com/css-modules/css-modules

CSSモジュールを使用する CSSファイルにCSSを自由に書くことができ、命名の衝突について心配する必要はありません。CSSモジュールによって処理されます。

この方法の利点は、特定のコンポーネントにスタイル機能を提供することです。これにより、次の開発者があなたのプロジェクトで作業するための、はるかに保守しやすいコードと読みやすいプロジェクトアーキテクチャが作成されます。

CSSファイルにスタイルを記述するのと比較して、Reactのスタイル属性には次の利点があります

  1. ツールjavascriptをプログラミング言語として使用する機能により、要素のスタイルを制御できます。これには、変数の埋め込み、条件の使用、スタイルの子コンポーネントへの受け渡しが含まれます。
  2. 「コンポーネント」アプローチ。コンポーネント用に記述されたHTML、JS、およびCSSコードの分離はありません。コンポーネントのコードは統合され、1か所に記述されます。

ただし、Reactのスタイル属性にはいくつかの欠点があります-できません

  1. メディアクエリを使用できません
  2. 擬似セレクターは使用できませんが、
  3. cSSクラスと比較すると効率が低い。

JSでCSSを使用すると、スタイルタグのすべての利点を得ることができ、それらの欠点はありません。今日現在、js-librariesには、Emotion、Styled-Components、Radiumなど、よくサポートされているcssがいくつかあります。これらのライブラリは、ReactがHTMLに対して行うCSSのようなものです。これらを使用すると、CSSを記述し、JSコードでCSSを制御できます。

単純な要素のスタイルを設定するためにコードがどのように見えるかを比較しましょう。 「hello world」divのスタイルを設定して、デスクトップでは大きく、モバイルでは小さく表示されるようにします。

style属性を使用

return (
   <div style={{fontSize:24}} className="hello-world">
      Hello world
   </div>
)

スタイルタグではメディアクエリを実行できないため、要素にclassNameを追加し、cssルールを追加する必要があります。

@media screen and (max-width: 700px){
   .hello-world {
      font-size: 16px; 
   }
}

Emotionの10 cssタグを使用

return (
   <div
      css={{
         fontSize: 24, 
         [CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY]:{
            fontSize: 16 
         }
      }
   >
      Hello world
   </div>
)

Emotionは、テンプレート文字列とスタイル付きコンポーネントもサポートしています。あなたが望むなら、あなたは書くことができます:

return (
   <Box>
      Hello world
   </Box>
)

const Box = styled.div`
   font-size: 24px; 
   ${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
      font-size: 16px; 
   }
`

内部では「CSS in JS」はcssクラスを使用しています。エモーションは特にパフォーマンスを念頭に置いて構築され、キャッシュを使用します。 Reactスタイル属性と比較して、JSのCssはパフォーマンスが向上します。

ベストプラクティス

推奨するベストプラクティスを次に示します。

  1. 要素をインラインまたはJSでスタイルする場合は、css-in-jsライブラリを使用し、スタイル属性は使用しないでください。

この方法ですべてのスタイリングを行うことを目指して、CSSファイルでスタイルをまったく指定しないでください。

  1. Css-in-jsソリューションを使用する場合、Cssファイルにスタイルを記述する必要はありません。 JSでCSSを作成するのは、JSが提供するプログラミング言語のすべてのツールを使用できるため、優れています。

インラインスタイルを完全に避けるべきですか?

  1. JSでスタイルコードを構造化することは、一般的にコードを構造化することにかなり似ています。例えば:
    • 繰り返されるスタイルを認識し、それらを1か所に記述します。エモーションでこれを行うには2つの方法があります。
// option 1 - Write common styles in CONSTANT variables
// styles.js
export const COMMON_STYLES = {
   BUTTON: css`
      background-color: blue; 
      color: white; 
      :hover {
         background-color: dark-blue; 
      }
   `
}

// SomeButton.js
const SomeButton = (props) => {
   ...
   return (
      <button
         css={COMMON_STYLES.BUTTON}
         ...
      >
         Click Me
      </button>
   )
}

// Option 2 - Write your common styles in a dedicated component 

const Button = styled.button`
   background-color: blue; 
   color: white; 
   :hover {
      background-color: dark-blue; 
   }   
`

const SomeButton = (props) => {
   ...
   return (
      <Button ...> 
         Click me
      </Button>
   )
}

  • Reactコーディングパターンはカプセル化されたコンポーネントです-コンポーネントを制御するHTMLとJSは1つのファイルに書き込まれます。それは、コンポーネントが属するスタイルを設定するためのCSS /スタイルコードです。

  • 必要に応じて、スタイリングプロップをコンポーネントに追加します。これにより、子コンポーネントで記述されたコードとスタイルを再利用し、親コンポーネントによって特定のニーズに合わせてカスタマイズできます。

const Button = styled.button([COMMON_STYLES.BUTTON, props=>props.stl])

const SmallButton = (props)=>(
   <Button 
      ...
      stl={css`font-size: 12px`}
   >
      Click me if you can see me
   </Button>
)

const BigButton = (props) => (
   <Button
      ...
      stl={css`font-size: 30px;`}
   >
      Click me
   </Button>
)
1
Ben Carp

コンポーネントからいくつかの要素をスタイルする必要がある場合がありますが、そのコンポーネントのみを表示する必要がある場合、またはスタイルがCSSクラスを使用する代わりに非常に少ない場合は、react jsのインラインスタイルを使用します。 reactjsのインラインスタイルはHTMLのインラインスタイルと同じですが、プロパティ名が少し異なります

Style = {{prop: "value"}}を使用して任意のタグにスタイルを記述します

import React, { Component } from "react";
    import { Redirect } from "react-router";

    class InlineStyle extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }

      render() {
        return (
          <div>
            <div>
              <div
                style={{
                  color: "red",
                  fontSize: 40,
                  background: "green"
                }}// this is inline style in reactjs
              >

              </div>
            </div>
          </div>
        );
      }
    }
    export default InlineStyle;
0
ABHIJEET KHIRE

JSXのスタイルは、HTMLのスタイルと非常によく似ています。

HTMLケース:

div style = "背景色:赤、色:白"

JSXケース:

divスタイル= {{backgroundColor: '赤'、色: '白'}}

0
Vivek Mehta