Skip to content

Latest commit

 

History

History
 
 

react

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Przewodnik stylistyczny React/JSX od Airbnb

Przeważnie rozsądne podejście do React i JSX

Spis treści

  1. Podstawowe zasady
  2. Class kontra React.createClass kontra bezklasowe
  3. Nazewnictwo
  4. Deklaracje
  5. Wyrównanie
  6. Cudzysłowy
  7. Spacjonowanie
  8. Właściwości - Props
  9. Nawiasy
  10. Znaczniki
  11. Metody
  12. Porządkowanie
  13. isMounted

Podstawowe zasady

Plik powinien zawierć tylko jeden komponent.

Class kontra React.createClass kontra bezstanowe

  • Jeżeli masz wewnętrzny stan i/albo odnośniki (refs), wtedy skłaniaj się ku wykorzystaniu class extends React.Component zamiast React.createClass, chyba że posiadasz dobry powód żeby użyć wstawek (mixins). eslint: react/prefer-es6-class react/prefer-stateless-function

    // źle
    const Listing = React.createClass({
      // ...
      render() {
        return <div>{this.state.hello}</div>;
      }
    });
    
    // dobrze
    class Listing extends React.Component {
      // ...
      render() {
        return <div>{this.state.hello}</div>;
      }
    }

    Jeśli nie masz stanu (state) lub odwołań (refs), wtedy zamiast klas wybierz normalną funkcję (funkcję anonimową ):

    // źle
    class Listing extends React.Component {
      render() {
        return <div>{this.props.hello}</div>;
      }
    }
    
    // źle (poleganie na inferencji (wnioskowaniu?) nazwy funkcji jest odradzane )
    const Listing = ({ hello }) => (
      <div>{hello}</div>
    );
    
    // dobrze
    function Listing({ hello }) {
      return <div>{hello}</div>;
    }

Nazewnictwo

  • Rozszrzenia: Dla komponentów React używaj rozszerzenia .jsx.

  • Nazwy plików: Dla nazw plików używaj PascalCase np.: ReservationCard.jsx.

  • Nazywanie struktur: Używaj PascalCase dla komponentów React i camelCase dla ich instancji. eslint: react/jsx-pascal-case

    // źle
    import reservationCard from './ReservationCard';
    
    // dobrze
    import ReservationCard from './ReservationCard';
    
    // źle
    const ReservationItem = <ReservationCard />;
    
    // dobrze
    const reservationItem = <ReservationCard />;
  • Nazywanie komponentów: Używaj nazw plików tak jak nazw komponentów. Na przykład odnośnik dla pliku ReservationCard.jsx powinien nazywać się ReservationCard. Jakkolwiek, dla komponentów podstawowych (root components) w katalogu, używaj index.jsx jako nazwy pliku i nazwy katalogu jako nazwy komponentu:

    // źle
    import Footer from './Footer/Footer';
    
    // źle
    import Footer from './Footer/index';
    
    // dobrze
    import Footer from './Footer';

Deklaracje

  • Nie używaj displayName dla nazw komponentów. W zamian nazwij komponent po jego odnośniku.

    // źle
    export default React.createClass({
      displayName: 'ReservationCard',
      // kod
    });
    
    // dobrze
    export default class ReservationCard extends React.Component {
    }

Wyrównanie

  • Podążaj za tymi stylami wyrównań dla składni JSX. eslint: react/jsx-closing-bracket-location

    // źle
    <Foo superLongParam="bar"
         anotherSuperLongParam="baz" />
    
    // dobrze
    <Foo
      superLongParam="bar"
      anotherSuperLongParam="baz"
    />
    // jeśli właściwości (props) mieszczą się w jednej lini wtedy utrzymaj je w jednej lini
    <Foo bar="bar" />
    
    // dzieci wyrównane są normalnie
    <Foo
      superLongParam="bar"
      anotherSuperLongParam="baz"
    >
      <Quux />
    </Foo>

Cudzysłowy

  • Zawsze używaj podwójnych cudzysłowów (") dla atrybutów JSX i apostrofów (') dla pozostałego kodu JS. eslint: jsx-quotes

Dlaczego? Atrybuty JSX nie mogą zawierać znaku modyfikacji przed apostrofami, węc cudzysłowy sprawiają że pisownia wyrazów takich "don't" jest łatwiesza w zapisie. Typowe atrybuty HTML także używają cudzysłowów zamiast apostofów, więc atrybuty JSX odzwierciedlają niniejszą konwencję.

```jsx
// źle
<Foo bar='bar' />

// dobrze
<Foo bar="bar" />

// źle
<Foo style={{ left: "20px" }} />

// dobrze
<Foo style={{ left: '20px' }} />
```

Spacjonowanie

  • Zawsze dodawaj pojedynczą spacje w samo-zamykanych tagach.

    // źle
    <Foo/>
    
    // bardzo źle
    <Foo                 />
    
    // źle
    <Foo
     />
    
    // dobrze
    <Foo />
  • Nie okładaj nawiasów klamrowych JSX ({}) spacjami. eslint: react/jsx-curly-spacing

    // źle
    <Foo bar={ baz } />
    
    // dobrze
    <Foo bar={baz} />

Właściwości - Props

  • Zawsze używaj camelCase for nazw własciwości.

    // źle
    <Foo
      UserName="hello"
      phone_number={12345678}
    />
    
    // dobrze
    <Foo
      userName="hello"
      phoneNumber={12345678}
    />
  • Unikaj ustawaienia wartości właściwości gdy wyraźnie przypisane jest jej true. eslint: react/jsx-boolean-value

    // źle
    <Foo
      hidden={true}
    />
    
    // dobrze
    <Foo
      hidden
    />
  • Zawsze dodawaj alternatywny opis (alt) dla znaczników <img>. Jeśli obraz ma właściwości prezentacyjne wtedy alt może pozostać pustym ciągiem albo, znacznik <img> powinien posiadać oznaczenie role="presentation". eslint: jsx-a11y/img-has-alt

    // źle
    <img src="hello.jpg" />
    
    // dobrze
    <img src="hello.jpg" alt="Me waving hello" />
    
    // dobrze
    <img src="hello.jpg" alt="" />
    
    // dobrze
    <img src="hello.jpg" role="presentation" />
  • Nie używaj słów takich jak: "obraz" albo "fotografia" we właściwościach <img> i alt. eslint: jsx-a11y/img-redundant-alt

Dlaczego? Czytniki ekranu ogłoszają już elementy img jako obrazy, więc nie ma potrzeby, aby umieszczać tę informację w tekście alt.

```jsx
// źle
<img src="hello.jpg" alt="Obraz przedsawiający machającą osobe" />

// dobrze
<img src="hello.jpg" alt="Machająca osbę" />
```
  • Używaj tylko poprawne, nie abstrakcyjne atrybutu role ARIA role. eslint: jsx-a11y/aria-role

    // źle - nie jest rolą ARIA
    <div role="datepicker" />
    
    // źle - abstrakcyjna ARIA role
    <div role="range" />
    
    // dobrze
    <div role="button" />
  • Nie używaj accessKey na elementach. eslint: jsx-a11y/no-access-key

Dlaczego? Niespójność pomiędzy skrótami klawiszowymi a komendami klawiszowymi wykorzystywanymi przez ludzi używających czytniki ekranu i klawiatury komplikuje dostępność.

// źle
<div accessKey="h" />

// dobrze
<div />
  • Unikaj używania indeksu tablicy jako klucza (key) właściwości, preferuj używanie unikalnego identyficatora (ID). (dlaczego?)
// źle
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

// dobrze
{todos.map((todo) =>
  <Todo
    {...todo}
    key={todo.id}
  />
)}

Nawiasy

  • W przypadku gdy tagów JSX jest więcej niż jeden, wtedy umieść je wewnątrz nawiasów (okrągłych). eslint: react/wrap-multilines

    // źle
    render() {
      return <MyComponent className="long body" foo="bar">
               <MyChild />
             </MyComponent>;
    }
    
    // dobrze
    render() {
      return (
        <MyComponent className="long body" foo="bar">
          <MyChild />
        </MyComponent>
      );
    }
    
    // dobrze, w przypadku jednej lini
    render() {
      const body = <div>hello</div>;
      return <MyComponent>{body}</MyComponent>;
    }

Znaczniki

  • Zawsze używaj samo-zamykających sie tagów w przypadku gdy nie zawierają one żadnych elementów potomnych. eslint: react/self-closing-comp

    // źle
    <Foo className="stuff"></Foo>
    
    // dobrze
    <Foo className="stuff" />
  • W przypadku gdy twój komponent ma właściwości na wielu liniach, wtedy umieść zamknięcie tagu na osobnej lini. eslint: react/jsx-closing-bracket-location

    // źle
    <Foo
      bar="bar"
      baz="baz" />
    
    // dobrze
    <Foo
      bar="bar"
      baz="baz"
    />

Metody

  • Używaj anonimowych funkcji żeby lokalne zmienne zakmnąć wewnątrz zasięgu.

    function ItemList(props) {
      return (
        <ul>
          {props.items.map((item, index) => (
            <Item
              key={item.key}
              onClick={() => doSomethingWith(item.name, index)}
            />
          ))}
        </ul>
      );
    }
  • Powiąrz obsługę zdarzeń dla metody renderowania w konstruktorze. eslint: react/jsx-no-bind

Dlaczego? Przywołanie metody łaczenia w ścieżce renderowania tworzy nową funkcję dla każdego renderowania.

```jsx
// źle
class extends React.Component {
  onClickDiv() {
    // zrób coś
  }

  render() {
    return <div onClick={this.onClickDiv.bind(this)} />
  }
}

// dobrze
class extends React.Component {
  constructor(props) {
    super(props);

    this.onClickDiv = this.onClickDiv.bind(this);
  }

  onClickDiv() {
    // zrób coś
  }

  render() {
    return <div onClick={this.onClickDiv} />
  }
}
```
  • Nie używaj podkreśleń do oznaczenia wewnętrznych metod komponentów React.

    // źle
    React.createClass({
      _onClickSubmit() {
        // zrób coś
      },
    
      // pozostały kod
    });
    
    // dobrze
    class extends React.Component {
      onClickSubmit() {
        // zrób coś
      }
    
      // pozostały kod
    }
  • Upewnij się by zawsze zwracać wartość w metodach render. eslint: require-render-return

    // źle
    render() {
      (<div />);
    }
    
    // dobrze
    render() {
      return (<div />);
    }

Porządkowanie

  • Kolejność dla class extends React.Component:
  1. opcjonalne methody static
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers albo eventHandlers tak onClickSubmit() albo onChangeDescription()
  12. metody get dla render tak getSelectReason() albo getFooterContent()
  13. Opcjonalne metody renderowania tak renderNavigation() albo renderProfilePicture()
  14. render
  • Jak definiować propTypes, defaultProps, contextTypes, itp.

    import React, { PropTypes } from 'react';
    
    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 <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
      }
    }
    
    Link.propTypes = propTypes;
    Link.defaultProps = defaultProps;
    
    export default Link;
  • Kolejność dla React.createClass: eslint: react/sort-comp

  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 albo eventHandlers tak onClickSubmit() albo onChangeDescription()
  19. metody get dla render like getSelectReason() albo getFooterContent()
  20. Opcjonalne metdoy renderowania like renderNavigation() albo renderProfilePicture()
  21. render

isMounted

Dlaczego? [isMounted jest antywzorcem][anti-pattern], nie jest dostępny gdy używane sa klasy ES6 i wkrótce zostanie oficijanie wycofany.

Tłumaczenia

Niniejszy przewodnik do JSX/React jest także dostępny w innych wersjach językowych:

⬆ powrót na górę