Лучший и разумный подход к 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 />); }
Это все с моей стороны… !!