Airbnb JavaScriptReactスタイルガイド
Airbnb Javascript React Style Guide
基本法
- ファイルには1つのコンポーネントしか含めることができません
- JSXを使用したシンタックスシュガー
- JSX以外のファイルからアプリを初期化しない限り、React.createElementを使用しないでください。 クラスとコンポーネント
クラスvsReact.createClassvsステートレス
- 状態参照を使用する場合は、
class extends React.Component
を使用するのが最適です。React.createClass
の代わりに。 eslint:react/prefer-es6-class
react/prefer-stateless-function
// 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 { }
整列
- JSX構文には、これらの配置スタイルを使用してください。エスリント:
react/jsx-closing-bracket-location
react/jsx-closing-tag-location
// 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
スペース
- 自閉症とラベルのスペース。エスリント:
no-multi-spaces
、react/jsx-tag-spacing
// bad // very bad // bad // good
// bad // good
- JSXの中括弧にはスペースがありません。エスリント:
react/jsx-curly-spacing
// bad // good
小道具
- 小さなこぶのある小道具
// bad // good
- propの値がtrueの場合、この値を無視して、prop名を直接書き込むことができます。エスリント:
react/jsx-boolean-value
// bad // good // good
alt
属性。画像が表現型の場合、alt
空の文字列にするかrole='presentation'
このプロパティが必要です。エスリント:jsx-a11y/alt-text
// bad // good // good // good
- a
alt
プロパティでは、「画像」、「写真」、「画像」という単語が使用されています。エスリント:jsx-a11y/img-redundant-alt
スクリーンリーダーはimgを画像として発音しているため、この情報を代替テキストに表示する必要はありません。
// bad // good
- 抽象的ではなく、使用のみ ARIAの役割 。スリング:
jsx-a11y/aria-role
// 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 }
参照
- refコールバック関数をお勧めします。エスリント:
react/no-string-refs
// bad // good { this.myRef = ref }} />
ブラケット
- JSXタグに複数の行がある場合は、括弧で囲みます。エスリント:
react/jsx-wrap-multilines
// 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 }
- あなたの
render
を確認してください関数には戻り値があります。エスリント:react/require-render-return
* ```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.