Лучший и разумный подход к React и JSX…

Основные правила …

  • Включайте только один компонент React в файл.
  • Тем не менее, для одного файла допускается использование нескольких компонентов без сохранения состояния или чистых компонентов. eslint: react/no-multi-comp.
  • Всегда используйте синтаксис JSX.
  • Не используйте React.createElement, если вы не инициализируете приложение из файла, который не является JSX.
  • react/forbid-prop-types разрешит arrays и objects только в том случае, если явно указано, что содержит array и object, используя arrayOf, objectOf или shape.

Класс против React.createClass против без гражданства

Если у вас есть внутреннее состояние и / или ссылки, предпочтительнее class extends React.Component, а не React.createClass. eslint: react/prefer-es6-class react/prefer-stateless-function

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

А если у вас нет состояния или ссылок, предпочтите обычные функции (не стрелочные функции) классам:

// bad
class Listing extends React.Component {
  render() {
    return <div>{this.props.hello}</div>;
  }
}
// bad (relying on function name inference is discouraged)
const Listing = ({ hello }) => (
  <div>{hello}</div>
);
// good
function Listing({ hello }) {
  return <div>{hello}</div>;

Соглашения об именах для приложения React (PascalCase против camelCase)

  • Расширения: используйте .jsx расширение для компонентов React. eslint: react/jsx-filename-extension
  • Имя файла: используйте PascalCase для имен файлов. Например, ReservationCard.jsx.
  • Ссылочное именование: используйте компоненты PascalCase для React и camelCase для их экземпляров. eslint: react/jsx-pascal-case
// bad
import reservationCard from './ReservationCard';

// good
import ReservationCard from './ReservationCard';

// bad
const ReservationItem = <ReservationCard />;

// good
const reservationItem = <ReservationCard />;

Именование компонентов: используйте имя файла в качестве имени компонента. Например, ReservationCard.jsx должно иметь ссылочное имя ReservationCard. Однако для корневых компонентов каталога используйте index.jsx в качестве имени файла и используйте имя каталога в качестве имени компонента:

// bad
import Footer from './Footer/Footer';

// bad
import Footer from './Footer/index';

// good
import Footer from './Footer';

Именование компонентов высшего порядка. Используйте сочетание имени компонента более высокого порядка и имени переданного компонента в качестве displayName на сгенерированном компоненте. Например, компонент высшего порядка withFooAlok() при передаче компонента Bar должен создать компонент с displayName равным withFooAlok(Bar).

Почему? displayName компонента может использоваться инструментами разработчика или в сообщениях об ошибках, и наличие значения, четко выражающего эту взаимосвязь, помогает людям понять, что происходит.

// bad
export default function withFooAlok(WrappedComponent) {
  return function WithFooAlok(props) {
    return <WrappedComponent {...props} foo />;
  }
}

// good
export default function withFooAlok(WrappedComponent) {
  function WithFooAlok(props) {
    return <WrappedComponent {...props} foo />;
  }

  const wrappedComponentName = WrappedComponent.displayName
    || WrappedComponent.name
    || 'Component';

  WithFooAlok.displayName = `withFooAlok(${wrappedComponentName})`;
  return WithFooAlok;
}

Именование свойств. Избегайте использования имен свойств компонентов DOM для разных целей.

Почему? Люди ожидают, что такие реквизиты, как style и className, будут означать одну конкретную вещь. Изменение этого API для подмножества вашего приложения делает код менее читаемым и менее удобным в обслуживании, а также может вызвать ошибки.

// bad
<MyComponent style="fancy" />

// bad
<MyComponent className="fancy" />

// good
<MyComponent variant="fancy" />

Декларация

Не используйте displayName для наименования компонентов. Вместо этого назовите компонент по ссылке.

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

Выравнивание в компоненте (файл .jsx) ‹Alok /›

Следуйте этим стилям выравнивания для синтаксиса JSX. eslint: react/jsx-closing-bracket-location react/jsx-closing-tag-location

// bad
<Foo superLongParam="bar"
     anotherSuperLongParam="baz" />
// good
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
/>
// if props fit in one line then keep it on the same line
<Foo bar="bar" />
// children get indented normally
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
>
  <Quux />
</Foo>
// bad
{showButton &&
  <Button />
}
// bad
{
  showButton &&
    <Button />
}
// good
{showButton && (
  <Button />
)}
// good
{showButton && <Button />}

Цитаты «очень важно» / «очень важно»

Всегда используйте двойные кавычки (") для атрибутов JSX, но одинарные кавычки (') для всех остальных JS. eslint: jsx-quotes

Почему? Обычные атрибуты HTML также обычно используют двойные кавычки вместо одинарных, поэтому атрибуты JSX отражают это соглашение.

// bad
<Foo bar='bar' />
// good
<Foo bar="bar" />
// bad
<Foo style={{ left: "20px" }} />
// good
<Foo style={{ left: '20px' }} />

Интервал…

Всегда включайте один пробел в самозакрывающийся тег. eslint: no-multi-spaces, react/jsx-tag-spacing

// bad
<Foo/>
// very bad
<Foo                 />
// bad
<Foo
 />
// good
<Foo />

Не заполняйте фигурные скобки JSX пробелами. eslint: react/jsx-curly-spacing

// bad
<Foo bar={ baz } />
// good
<Foo bar={baz} />

Реквизит (… / ‹Alok companyName =” GL ”/›)

Всегда используйте camelCase для имен свойств.

// bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>
// good
<Foo
  userName="hello"
  phoneNumber={12345678}
/>

Опускайте значение свойства, если оно явно true. eslint: react/jsx-boolean-value

// bad
<Alok
  hidden={true}
/>
// good
<Alok
  hidden
/>
// good
<Alok hidden />

Всегда включайте alt опору в теги <img>. Если изображение презентационное, alt может быть пустой строкой или <img> должно содержать role="presentation". eslint: jsx-a11y/alt-text

// bad
<img src="hello.jpg" />
// good
<img src="hello.jpg" alt="Me waving hello" />
// good
<img src="hello.jpg" alt="" />
// good
<img src="hello.jpg" role="presentation" />

Не используйте такие слова, как «изображение», «фото» или «изображение» в <img> alt реквизитах. eslint: jsx-a11y/img-redundant-alt

Почему? Программы чтения с экрана уже объявляют img элементы как изображения, поэтому нет необходимости включать эту информацию в замещающий текст.

// bad
<img src="hello.jpg" alt="Picture of me waving hello" />
// good
<img src="hello.jpg" alt="Me waving hello" />

Не используйте accessKey на элементах. eslint: jsx-a11y/no-access-key

Почему? Несоответствие между сочетаниями клавиш и командами клавиатуры, используемыми людьми, использующими программы чтения с экрана и клавиатуру, усложняет доступность.

// bad
<div accessKey="h" />
// good
<div />

Избегайте использования индекса массива как key prop, предпочитайте стабильный идентификатор. eslint: react/no-array-index-key

Почему? Отказ от использования стабильного идентификатора является анти-шаблоном, поскольку он может отрицательно сказаться на производительности и вызвать проблемы с состоянием компонентов.

Мы не рекомендуем использовать индексы для ключей, если порядок элементов может измениться.

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

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

Ссылки в React [ref = {(ref) = ›{this.myRef = ref; }}]

Всегда используйте обратные вызовы ref. eslint: react/no-string-refs

// bad
<Foo
  ref="myRef"
/>
// good
<Foo
  ref={(ref) => { this.myRef = ref; }}
/>

Скобки ( )

Если теги JSX занимают более одной строки, заключайте их в круглые скобки. eslint: react/jsx-wrap-multilines

// bad
render() {
  return <MyComponent variant="long body" foo="bar">
           <MyChild />
         </MyComponent>;
}
// good
render() {
  return (
    <MyComponent variant="long body" foo="bar">
      <MyChild />
    </MyComponent>
  );
}
// good, when single line
render() {
  const body = <div>hello</div>;
  return <MyComponent>{body}</MyComponent>;
}

Теги ‹/›

Всегда закрывайте теги, у которых нет дочерних элементов. eslint: react/self-closing-comp

// bad
<Foo variant="stuff"></Foo>
// good
<Foo variant="stuff" />

Если ваш компонент имеет многострочные свойства, закройте его тег на новой строке. eslint: react/jsx-closing-bracket-location

// bad
<Foo
  bar="bar"
  baz="baz" />
// good
<Foo
  bar="bar"
  baz="baz"
/>

Методы = () = ›{}

Используйте стрелочные функции, чтобы закрыть локальные переменные. Это удобно, когда вам нужно передать дополнительные данные в обработчик событий. Однако убедитесь, что они не сильно ухудшают производительность, особенно при передаче пользовательским компонентам, которые могут быть PureComponents, потому что они каждый раз будут запускать, возможно, ненужный повторный рендеринг.

function ItemList(props) {
  return (
    <ul>
      {props.items.map((item, index) => (
        <Item
          key={item.key}
          onClick={(event) => { doSomethingWith(event, item.name, index); }}
        />
      ))}
    </ul>
  );
}

Свяжите обработчики событий для метода рендеринга в конструкторе. eslint: react/jsx-no-bind

Почему? Вызов привязки в пути рендеринга создает новую функцию при каждом рендеринге. Не используйте стрелочные функции в полях класса, потому что это затрудняет их тестирование и отладку и может отрицательно сказаться на производительности, а также потому, что концептуально поля класса предназначены для данных, а не для логики.

// bad
class extends React.Component {
  onClickDiv() {
    // do stuff
  }
  render() {
    return <div onClick={this.onClickDiv.bind(this)} />;
  }
}
// very bad
class extends React.Component {
  onClickDiv = () => {
    // do stuff
  }
  render() {
    return <div onClick={this.onClickDiv} />
  }
}
// good
class extends React.Component {
  constructor(props) {
    super(props);
    this.onClickDiv = this.onClickDiv.bind(this);
  }
  onClickDiv() {
    // do stuff
  }
  render() {
    return <div onClick={this.onClickDiv} />;
  }
}

Не используйте префикс подчеркивания для внутренних методов компонента React.

Почему? Префиксы подчеркивания иногда используются в других языках в качестве соглашения для обозначения конфиденциальности. Но, в отличие от этих языков, в JavaScript нет встроенной поддержки конфиденциальности, все общедоступно. Независимо от ваших намерений, добавление префиксов подчеркивания к вашим свойствам на самом деле не делает их частными, и любое свойство (с префиксом подчеркивания или без него) следует рассматривать как общедоступное. См. Вопросы # 1024 и # 490 для более подробного обсуждения.

// bad
React.createClass({
  _onClickSubmit() {
    // do stuff
  },
  // other stuff
});
// good
class extends React.Component {
  onClickSubmit() {
    // do stuff
  }
  // other stuff
}

Обязательно возвращайте значение в ваших render методах. eslint: react/require-render-return

// bad
render() {
  (<div />);
}
// good
render() {
  return (<div />);
}

Это все с моей стороны… !!