asattelmaier / react-style-guide

German Translation of Airbnb React/JSX Style Guide

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Airbnb React/JSX Style Guide

Ein erfahrungsgemäß angemessener Ansatz für React und JSX

Dieser Style Guide basiert auf die aktuell vorherrschenden Javascript Standards, obwohl ein paar Konventionen (z.B. async/await oder statische Klassenvariablen) noch aufgenommen oder von Fall zu Fall verboten werden können. Derzeit ist alles, was vor der „stage 3“ liegt, weder in diesem Handbuch enthalten noch empfohlen.

Inhaltsverzeichnis

  1. Grundregeln
  2. Class vs React.createClass vs zustandslos
  3. Mixins
  4. Namensgebung
  5. Deklarierung
  6. Ausrichtung
  7. Anführungszeichen
  8. Abstände
  9. Props
  10. Refs
  11. Klammern
  12. Tags
  13. Methoden
  14. Anordnung
  15. isMounted

Grundregeln

  • Eine Datei darf nur eine React Komponente enthalten.
  • Verwende immer die JSX Syntax.
  • Verwende React.createElement nur, wenn die App nicht aus einer JSX Datei initialisiert wird.
  • react/forbid-prop-types erlaubt arrays und objects nur, wenn explizit angegeben wird was arrays und objects enthält, unter der Verwendung von arrayOf, objectOf oder shape.

Class vs React.createClass vs zustandslos

  • Bei einem internen „state“ und/oder „refs“, ist class extends React.Component, React.createClass vorzuziehen. eslint: react/prefer-es6-class react/prefer-stateless-function

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

    Bei keinem „state“ oder „refs“, werden normale Funktionen (keine Pfeilfunktionen) gegenüber Klassen bevorzugt:

    // schlecht
    class Listing extends React.Component {
      render() {
        return <div>{this.props.hello}</div>;
      }
    }
    
    // schlecht (es wird abgeraten sich auf die Schlussfolgerung des Funktionsnamens zu verlassen)
    const Listing = ({ hello }) => (
      <div>{hello}</div>
    );
    
    // gut
    function Listing({ hello }) {
      return <div>{hello}</div>;
    }

Mixins

Warum? Mixins eröffnen implizite Abhängigkeiten, versuchsachen Namenskonflikte und eine beschleunigende Komplexität. Die meisten Anwendungsfälle für Mixins lassen sich besser über Komponenten, höhere Komponenten oder Utility-Module realisieren.

Namensgebung

  • Erweiterungen: Verwende .jsx Erweiterungen für React Komponenten. eslint: react/jsx-filename-extension

  • Dateiname: Verwende PascalCase für Dateinamen. Z.B., ReservationCard.jsx.

  • Benennung der Referenzen: Verwende PascalCase für React Komponenten und camelCase für seine Instanzen. eslint: react/jsx-pascal-case

    // schlecht
    import reservationCard from './ReservationCard';
    
    // gut
    import ReservationCard from './ReservationCard';
    
    // schlecht
    const ReservationItem = <ReservationCard />;
    
    // gut
    const reservationItem = <ReservationCard />;
  • Benennung der Komponenten: Verwende den Dateinamen als Komponentenname. Zum Beispiel, ReservationCard.jsx sollte folgenden Referenznamen haben ReservationCard. Allerdings sollte für eine Root Komponente eines Ordners index.jsx als Dateiname verwendet werden und der Ordnername als Komponentenname:

    // schlecht
    import Footer from './Footer/Footer';
    
    // schlecht
    import Footer from './Footer/index';
    
    // gut
    import Footer from './Footer';
  • Bennenung höherer Komponenten: Verwende eine Komination vom Namen der höheren Komponente und den Namen der übergebenden Komponenten als den displayName der erzeugten Komponente. Zum Beispiel, wenn die höhere Komponente withFoo(), die Komponente Bar übergibt, sollte eine Komponente mit einem displayName von withFoo(Bar) erzeugen.

    Warum? Der displayName einer Komponente könnte von Entwicklertools oder Fehlermeldungen verwendet werden und einen Wert zu haben, der klar ist und die Beziehung angibt hilft um zu verstehen was passiert.

    // schlecht
    export default function withFoo(WrappedComponent) {
      return function WithFoo(props) {
        return <WrappedComponent {...props} foo />;
      }
    }
    
    // gut
    export default function withFoo(WrappedComponent) {
      function WithFoo(props) {
        return <WrappedComponent {...props} foo />;
      }
    
      const wrappedComponentName = WrappedComponent.displayName
        || WrappedComponent.name
        || 'Component';
    
      WithFoo.displayName = `withFoo(${wrappedComponentName})`;
      return WithFoo;
    }
  • Bennenung der Props: Vermeide die Verwendung von DOM Komponenten Prop-Namen für verschiedene Vorhaben.

    Warum? Man erwartet, wie bei style und className, dass Props genau eine spezielle Sache bedeuten. Durch das Ändern dieser API für Untergruppen der App, wird der Code weniger lesbar und wartbar und kann Fehler verursachen.

    // schlecht
    <MyComponent style="fancy" />
    
    // schlecht
    <MyComponent className="fancy" />
    
    // gut
    <MyComponent variant="fancy" />

Deklarierung

  • Verwende nicht displayName für die Benennung von Komponenten. Benenne stattdessen die Komponente durch die Referenz.

    // schlecht
    export default React.createClass({
      displayName: 'ReservationCard',
      // stuff goes here
    });
    
    // gut
    export default class ReservationCard extends React.Component {
    }

Ausrichtung

  • Folge diese Ausrichtungsstil für die JSX Syntax. eslint: react/jsx-closing-bracket-location react/jsx-closing-tag-location

    // schlecht
    <Foo superLongParam="bar"
         anotherSuperLongParam="baz" />
    
    // gut
    <Foo
      superLongParam="bar"
      anotherSuperLongParam="baz"
    />
    
    // Wenn die Props auf eine Zeile passen, dann halte sie auf der gleichen Zeile.
    <Foo bar="bar" />
    
    // Kinder werden normal eingerückt
    <Foo
      superLongParam="bar"
      anotherSuperLongParam="baz"
    >
      <Quux />
    </Foo>
    
    // schlecht
    {showButton &&
      <Button />
    }
    
    // schlecht
    {
      showButton &&
        <Button />
    }
    
    // gut
    {showButton && (
      <Button />
    )}
    
    // gut
    {showButton && <Button />}

Anführungszeichen

  • Verwende immer doppelte Anführungszeichen (") für JSX Attribute aber einfache Anführungszeichen (') für alles andere JS. eslint: jsx-quotes

    Warum? Normale HTML Attribute verwenden typischerweise auch doppelte Anführungszeichen anstatt einfache und JSX spiegelt diese Konvention wieder.

    // schlecht
    <Foo bar='bar' />
    
    // gut
    <Foo bar="bar" />
    
    // schlecht
    <Foo style={{ left: "20px" }} />
    
    // gut
    <Foo style={{ left: '20px' }} />

Abstände

  • Füge immer ein einzelnes Leerzeichen in selbstschließendes Tag ein. eslint: no-multi-spaces, react/jsx-tag-spacing

    // schlecht
    <Foo/>
    
    // sehr schlecht
    <Foo                 />
    
    // schlecht
    <Foo
     />
    
    // gut
    <Foo />
  • Fülle die geschweiften JSX-Klammern nicht mit Zwischenräumen. eslint: react/jsx-curly-spacing

    // schlecht
    <Foo bar={ baz } />
    
    // gut
    <Foo bar={baz} />

Props

  • Benutze immer camelCase für Props Namen.

    // schlecht
    <Foo
      UserName="hello"
      phone_number={12345678}
    />
    
    // gut
    <Foo
      userName="hello"
      phoneNumber={12345678}
    />
  • Lasse den Wert der Prop weg, wenn er immer explizit true ist. eslint: react/jsx-boolean-value

    // schlecht
    <Foo
      hidden={true}
    />
    
    // gut
    <Foo
      hidden
    />
    
    // gut
    <Foo hidden />
  • Gebe immer ein alt Prop an <img> Tags an. Wenn das Bild repräsentativ ist, kann alt ein leerer String sein oder der <img> Tag muss role="presentation" haben. eslint: jsx-a11y/alt-text

    // schlecht
    <img src="hello.jpg" />
    
    // gut
    <img src="hello.jpg" alt="Me waving hello" />
    
    // gut
    <img src="hello.jpg" alt="" />
    
    // gut
    <img src="hello.jpg" role="presentation" />
  • Verwende keine Wörter wie "image", "photo" oder "picture" in <img> alt Props. eslint: jsx-a11y/img-redundant-alt

    Warum? Screenreader geben img Elemente bereits als Bilder an, darum muss man diese Information nicht im alt Text mit angeben.

    // schlecht
    <img src="hello.jpg" alt="Picture of me waving hello" />
    
    // gut
    <img src="hello.jpg" alt="Me waving hello" />
  • Verwende nur gültige, keine abstrakten ARIA Regeln. eslint: jsx-a11y/aria-role

    // schlecht - keine ARIA Regel
    <div role="datepicker" />
    
    // schlecht - abstrakte ARIA Regel
    <div role="range" />
    
    // gut
    <div role="button" />
  • Verwende nicht accessKey an Elementen. eslint: jsx-a11y/no-access-key

Warum? Inkonsistenzen zwischen Tastaturkürzeln und Tastaturbefehlen, die von Personen verwendet werden, die Screenreader und Tastaturen verwenden, erschweren die Zugänglichkeit.

// schlecht
<div accessKey="h" />

// gut
<div />

Warum? Keine feste ID zu verwenden ist ein Anit-Pattern weil es die Leistung negativ beeinflussen und Probleme mit dem Komponentenzustand verursachen kann.

Wir empfehlen nicht, Indizes für Schlüssel zu verwenden, wenn sich die Reihenfolge der Elemente ändern kann.

// schlecht
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

// gut
{todos.map(todo => (
  <Todo
    {...todo}
    key={todo.id}
  />
))}
  • Definiere immer explizite Standard-Props für alle nicht benötigten Props.

Warum? propTypes sind eine Form der Dokumentation und durch das Anbieten von defaultProps muss der Leser des Codes keine großen Annahmen machen. Zusätzlich are a form of documentation, and providing defaultProps means the reader of your code doesn’t have to assume as much. Darüber hinaus kann es bedeuten, dass der Code bestimmte Typenprüfungen weglassen kann.

// schlecht
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
  foo: PropTypes.number.isRequired,
  bar: PropTypes.string,
  children: PropTypes.node,
};

// gut
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
  foo: PropTypes.number.isRequired,
  bar: PropTypes.string,
  children: PropTypes.node,
};
SFC.defaultProps = {
  bar: '',
  children: null,
};
  • Verwende verteilte Props sparsam.

Warum? Andernfalls ist es wahrscheinlicher, dass unnötige Props an Komponenten weitergeben. Und für React v15.6.1 und älter, kannst du ungültige HTML Attribute an den DOM weitergeben.

Ausnahmen:

  • Höhere Komponenten (HOC) die Proxy-Props weitergeben und propTypes hochziehen
function HOC(WrappedComponent) {
  return class Proxy extends React.Component {
    Proxy.propTypes = {
      text: PropTypes.string,
      isLoading: PropTypes.bool
    };

    render() {
      return <WrappedComponent {...this.props} />
    }
  }
}
  • Ausbreiten von Objekten mit bekannten, expliziten Props. Dies kann besonders nützlich sein, wenn React-Komponenten mit Mochas beforeEach-Konstrukt getestet werden.
export default function Foo {
  const props = {
    text: '',
    isPublished: false
  }

  return (<div {...props} />);
}

Hinweise zur Verwendung: Filter überflüssig Props wenn möglich heraus. Verwenden auch prop-types-exact um Bugs zu verhindern.

// schlecht
render() {
  const { irrelevantProp, ...relevantProps  } = this.props;
  return <WrappedComponent {...this.props} />
}

// gut
render() {
  const { irrelevantProp, ...relevantProps  } = this.props;
  return <WrappedComponent {...relevantProps} />
}

Refs

  • Verwende immer Ref Callbacks. eslint: react/no-string-refs

    // schlecht
    <Foo
      ref="myRef"
    />
    
    // gut
    <Foo
      ref={(ref) => { this.myRef = ref; }}
    />

Klammern

  • Umschließe JSX Tags in Klammern, wenn sie mehr als eine Zeile umfassen. eslint: react/jsx-wrap-multilines

    // schlecht
    render() {
      return <MyComponent variant="long body" foo="bar">
               <MyChild />
             </MyComponent>;
    }
    
    // gut
    render() {
      return (
        <MyComponent variant="long body" foo="bar">
          <MyChild />
        </MyComponent>
      );
    }
    
    // gut, wenn einzeilig
    render() {
      const body = <div>hello</div>;
      return <MyComponent>{body}</MyComponent>;
    }

Tags

  • Bei keinen Kindern, immer selbstschließende Tags. eslint: react/self-closing-comp

    // schlecht
    <Foo variant="stuff"></Foo>
    
    // gut
    <Foo variant="stuff" />
  • Hat die Komponente mehrzeilige Eigenschaften, schließe den Tag auf einer neuen Zeile. eslint: react/jsx-closing-bracket-location

    // schlecht
    <Foo
      bar="bar"
      baz="baz" />
    
    // gut
    <Foo
      bar="bar"
      baz="baz"
    />

Methoden

  • Verwende Pfeilfunktionen, um lokale Variablen zu schließen.

    function ItemList(props) {
      return (
        <ul>
          {props.items.map((item, index) => (
            <Item
              key={item.key}
              onClick={() => doSomethingWith(item.name, index)}
            />
          ))}
        </ul>
      );
    }
  • Binde Eventhandler für die Rendermethode im Konstruktor. eslint: react/jsx-no-bind

    Warum? Ein bind-Aufruf in der Render-Methode erstellt bei jedem Aufruf von Render eine neue Funktion.

    // schlecht
    class extends React.Component {
      onClickDiv() {
        // do stuff
      }
    
      render() {
        return <div onClick={this.onClickDiv.bind(this)} />;
      }
    }
    
    // gut
    class extends React.Component {
      constructor(props) {
        super(props);
    
        this.onClickDiv = this.onClickDiv.bind(this);
      }
    
      onClickDiv() {
        // do stuff
      }
    
      render() {
        return <div onClick={this.onClickDiv} />;
      }
    }
  • Verwende kein Unterstrich-Präfix für interne Methoden einer React-Komponente.

    Warum? Unterstich-Präfixe werden in manchen Sprachen als Konvention verwendet um etwas als privat zu kennzeichnen. Aber anders als in diesen Sprachen unterstützt JavaScript die Kennzeichnung von privat nicht nativ, alles ist öffentlich. Unabhängig von den Absichten macht das Hinzufügen eines Unterstich-Präfix die Eigenschaft nicht privat und jede Eigenschaft (mit Unterstrich-Präfix oder nicht) sollte als öffentlich behandelt werden. Siehe das folgende Problem #1024, and #490 für eine tiefere Diskussion.

    // schlecht
    React.createClass({
      _onClickSubmit() {
        // mache bestimmte Dinge
      },
    
      // mache bestimmte Dinge
    });
    
    // gut
    class extends React.Component {
      onClickSubmit() {
        // mache bestimmte Dinge
      }
    
      // mache andere Dinge
    }
  • Stelle sicher, dass ein Wert in der render Methode zurückgegeben wird. eslint: react/require-render-return

    // schlecht
    render() {
      (<div />);
    }
    
    // gut
    render() {
      return (<div />);
    }

Anordnung

  • Anordnung für class extends React.Component:
  1. Optionale static Methoden
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers oder eventHandlers wie onClickSubmit() oder onChangeDescription()
  12. getter Methoden für render wie getSelectReason() oder getFooterContent()
  13. Optionale render Methods wie renderNavigation() oder renderProfilePicture()
  14. render
  • Definition von propTypes, defaultProps, contextTypes, etc...

    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 <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>;
      }
    }
    
    Link.propTypes = propTypes;
    Link.defaultProps = defaultProps;
    
    export default Link;
  • Anordnung von 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 oder eventHandlers wie onClickSubmit() oder onChangeDescription()
  19. getter Methods für render wie getSelectReason() oder getFooterContent()
  20. Optionale render Methoden wie renderNavigation() oder renderProfilePicture()
  21. render

isMounted

Warum? isMounted ist ein Anti-Pattern, es ist unter ES6 Klassen nicht verfügbar und es ist auf dem Weg offiziell als veraltet zu gelten.

Übersetzungen

Dieser JSX/React Style Guide ist auch in anderen Sprachen verfügbar:

⬆ zurück zum Anfang

About

German Translation of Airbnb React/JSX Style Guide