Airbnb JavaScriptReactスタイルガイド



Airbnb Javascript React Style Guide



基本法


  • ファイルには1つのコンポーネントしか含めることができません
  • JSXを使用したシンタックスシュガー
  • JSX以外のファイルからアプリを初期化しない限り、React.createElementを使用しないでください。 クラスとコンポーネント

クラスvsReact.createClassvsステートレス


// bad const Listing = React.createClass({ // ... render() { return {this.state.hello} } }) // good class Listing extends React.Component { // ... render() { return {this.state.hello} } }
  • state、refsを使用しない場合は、クラスの代わりに通常の関数(矢印関数ではない)を使用することをお勧めします。
// bad class Listing extends React.Component { render() { return {this.props.hello} } } // bad (independent of function name inference - relying on function name inference is discouraged) const Listing = ({ hello }) => ( {hello} ) // good function Listing({ hello }) { return {hello} }

Mixins


どうして? mixinsはいくつかの暗黙の依存関係を導入し、名前の競合を引き起こし、雪だるま式に複雑になる可能性があります。ほとんどの場合、ミックスインはコンポーネントを渡すことができますが、 高レベルのコンポーネントHOC または、ツールモジュールの方が適切に実装されています。

名前


  • 拡張子名.jsxを使用コンポーネント拡張として。



  • ファイル名 :ファイル名として次のように大きなこぶを使用します:ReservationCard.jsx

  • パラメータの命名 :Reactコンポーネントは大きなこぶを使用し、コンポーネントの例は小さなこぶを使用します。エスリント: react/jsx-pascal-case
    インスタンス



// bad import reservationCard from './ReservationCard' // good import ReservationCard from './ReservationCard' // bad const ReservationItem = // good const reservationItem =
  • コンポーネントの命名 :ファイル名はコンポーネント名です。例:ReservationCard.jsxは、パラメーター名としてReservationCardを使用する必要があります。ただし、フォルダー内のコンポーネントの場合、ファイル名としてindex.jsxを使用し、コンポーネント名としてフォルダー名を使用する必要があります。
// bad import Footer from './Footer/Footer' // bad import Footer from './Footer/index' // good import Footer from './Footer'
  • 高次コンポーネントのHOCネーミング :生成されたコンポーネントのdisplayNameとして、上位のコンポーネント名と渡されたコンポーネント名の組み合わせを使用します。たとえば、高レベルのコンポーネントwithFoo()は、コンポーネントBarで渡されると、displayNameプロパティがwithFoo(Bar)である新しいコンポーネントを生成する必要があります。

どうして?コンポーネントのdisplayNameは、開発者ツールまたはエラーメッセージで使用でき、このコンポーネントの関係を明確に表す値があります。これは、人々が何が起こっているのかを理解するのに役立ちます。

// bad export default function withFoo(WrappedComponent) { return function WithFoo(props) { return } } // good export default function withFoo(WrappedComponent) { function WithFoo(props) { return } const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component' WithFoo.displayName = `withFoo(${wrappedComponentName})` return WithFoo }
  • 小道具の命名 :DOMコンポーネントの属性名を使用して異なる意味を表現することは避けてください

人々は、属性styleとclassNameが明確な意味を表すことを期待しています。アプリケーションのサブセットに対してこのAPIを変更すると、コードが読みにくくなり、保守しにくくなり、エラーが発生する可能性があります。

// bad // bad // good

ステートメント


  • displayNameでコンポーネントに名前を付けないでください。参照によってコンポーネントに名前を付けるのが最善です。
// bad export default React.createClass({ displayName: 'ReservationCard', // stuff goes here }) // good export default class ReservationCard extends React.Component { }

整列


// bad // good // If you can put it on one line, you can also use a single line // The label inside Foo is normally indented // bad {showButton && } // bad { showButton && } // good {showButton && ( )} // good {showButton && }

引用符


  • JSX属性(')では二重引用符を使用しますが、js(')では一重引用符を使用します。eslint: jsx-quotes

どうして?通常のHTML属性も一重引用符ではなく二重引用符を使用するため、JSX属性もこの規則を使用します。



// bad // good // bad // good

スペース


// bad // very bad // bad // good // bad // good // bad // good

小道具


  • 小さなこぶのある小道具
// bad // good
  • propの値がtrueの場合、この値を無視して、prop名を直接書き込むことができます。エスリント: react/jsx-boolean-value
// bad // good // good
  • タグは通常設定されますalt属性。画像が表現型の場合、alt空の文字列にするか role='presentation'このプロパティが必要です。エスリント: jsx-a11y/alt-text
// bad // good Me waving hello // good // good
  • a altプロパティでは、「画像」、「写真」、「画像」という単語が使用されています。エスリント: jsx-a11y/img-redundant-alt スクリーンリーダーはimgを画像として発音しているため、この情報を代替テキストに表示する必要はありません。
// bad Picture of me waving hello // good Me waving hello // bad - not an ARIA role // bad - abstract ARIA role // good
  • 要素には使用しないでくださいaccessKey。eslint: jsx-a11y/no-access-key スクリーンリーダーとキーボードを使用する人々が使用するキーボードショートカットとキーボードコマンドの不一致により、アクセシビリティが複雑になります。
// bad // good
  • 配列の添え字をキー属性として使用することは避けてください。安定したIDを使用することをお勧めします

スタビライザーバーなしのID アンチパターンです コンポーネントのパフォーマンスに悪影響を与える可能性があり、コンポーネントのステータスに問題が発生する傾向があります。配列要素が変更される可能性がある場合は、キーとして添え字を使用することはお勧めしません。

// bad {todos.map((todo, index) => )} // good {todos.map(todo => ( ))}
  • 必須ではないすべての属性に明示的なデフォルト値を定義します。

propTypesはドキュメントフォームであり、デフォルトのプロパティを提供することは、ユーザーが多くの値を想定する必要がないことを意味します。さらに、これは、コードが型チェックを無視できることも意味します。

// bad function SFC({ foo, bar, children }) { return {foo}{bar}{children} } SFC.propTypes = { foo: PropTypes.number.isRequired, bar: PropTypes.string, children: PropTypes.node, } // good function SFC({ foo, bar, children }) { return {foo}{bar}{children} } SFC.propTypes = { foo: PropTypes.number.isRequired, bar: PropTypes.string, children: PropTypes.node, } SFC.defaultProps = { bar: '', children: null, }
  • 不要なpropsプロパティをコンポーネントに渡す場合を除いて、props拡張演算子は慎重に使用してください。両方とも{... props}です。また、v15.6.1以前のReactでは、次のことができます。 HTML以外の属性をDOM要素に渡す
    例外:

HOCはプロキシ小道具と小道具propTypesです

function HOC(WrappedComponent) { return class Proxy extends React.Component { Proxy.propTypes = { text: PropTypes.string, isLoading: PropTypes.bool } render() { return } } }
  • 明示的なプロパティを使用して既知のオブジェクトを拡張することもできます。これは、MochaのbeforeEach関数を使用して単一のテストを実行する場合に特に役立ちます。
// bad export default function Foo { const props = { text: '', isPublished: false } return ( ) }
  • 使用方法:不要な属性を可能な限り除外します。同時に prop-type-exact バグを避けるために助けに行きなさい。
// bad render() { const { irrelevantProp, ...relevantProps } = this.props return } // good render() { const { irrelevantProp, ...relevantProps } = this.props return }

参照


// bad // good { this.myRef = ref }} />

ブラケット


// bad render() { return } // good render() { return ( ) } // good, single line can be written directly render() { const body = hello return {body} }

ラベル


  • 子要素がない場合は、自動終了ラベルを使用するのが最適です。エスリント: react/self-closing-comp
// bad // good
  • コンポーネントに複数行の属性がある場合は、終了タグだけを終了行として使用します。エスリント: react/jsx-closing-bracket-location
// bad // good

方法


  • 矢印関数でローカル変数をオフにします。
function ItemList(props) { return (
    {props.items.map((item, index) => ( doSomethingWith(item.name, index)} /> ))}
) }
  • コンストラクターでイベントハンドラーをバインドします。エスリント: react/jsx-no-bind

なぜへの呼びかけ?レンダリング関数は、レンダリングされるたびに新しい関数を作成します。

// bad class extends React.Component { onClickDiv() { // do stuff } render() { return } } // good class extends React.Component { constructor(props) { super(props) this.onClickDiv = this.onClickDiv.bind(this) } onClickDiv() { // do stuff } render() { return } }
  • Reactコンポーネントの内部メソッド名のプレフィックスとしてアンダースコアを使用しないでください。

下線付きのプレフィックスは、他の言語の私的言語を参照するために使用されることがあります。しかし、JavaScriptはネイティブでプライベートをサポートしておらず、すべてがパブリックです。あなたの意図ではありますが、プロパティにアンダースコアプレフィックスを追加することは、実際にはプライベートプロパティではなく、プロパティ(アンダースコアプレフィックスであるかどうかに関係なく)はパブリックと見なされます。問題を詳細に見る #1024 、と #490

// bad React.createClass({ _onClickSubmit() { // do stuff }, // other stuff }) // good class extends React.Component { onClickSubmit() { // do stuff } // other stuff } * ```source-js-jsx // bad render() { ( ) } // good render() { return ( ) } ``` ### Sorting --- - The order of the internal attributes of `class extends React.Component`: 1. Optional `static` method 2. `constructor` 3. `getChildContext` 4. `componentWillMount` 5. `componentDidMount` 6. `componentWillReceiveProps` 7. `shouldComponentUpdate` 8. `componentWillUpdate` 9. `componentDidUpdate` 10. `componentWillUnmount` 11. *clickHandlers or eventHandlers* such as: `onClickSubmit()`, `onChangeDescription()` 12. *getter methods for `render`* such as: `getSelectReason()`, `getFooterContent()` 13. *optional render methods* such as: `renderNavigation()`, `renderProfilePicture()` 14. `render` - How to define `propTypes`, `defaultProps`, `contextTypes`, etc... ```source-js-jsx import React from 'react' import PropTypes from 'prop-types' const propTypes = { id: PropTypes.number.isRequired, url: PropTypes.string.isRequired, text: PropTypes.string, } const defaultProps = { text: 'Hello World', } class Link extends React.Component { static methodsAreOk() { return true } render() { return {this.props.text} } } Link.propTypes = propTypes Link.defaultProps = defaultProps export default Link ``` - `React.createClass` internal attribute ordering: eslint: [`react/sort-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp. Md) 1. `displayName` 2. `propTypes` 3. `contextTypes` 4. `childContextTypes` 5. `mixins` 6. `statics` 7. `defaultProps` 8. `getDefaultProps` 9. `getInitialState` 10. `getChildContext` 11. `componentWillMount` 12. `componentDidMount` 13. `componentWillReceiveProps` 14. `shouldComponentUpdate` 15. `componentWillUpdate` 16. `componentDidUpdate` 17. `componentWillUnmount` 18. *clickHandlers or eventHandlers* such as: `onClickSubmit()`, `onChangeDescription()` 19. *getter methods for `render`* such as: `getSelectReason()`, `getFooterContent()` 20. *optional render methods* such as: `renderNavigation()`, `renderProfilePicture()` 21. `render` ### isMounted --- - Do not use `isMounted`. Eslint: [`react/no-is-mounted`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md) > Why? [`isMounted` is anti-pattern][anti-pattern], which is not allowed in the ES6 class and will be officially discarded.