Несколько практических советов для улучшения качества кода опубликовал сайт proglib.io в своем переводе статьи «21 Best Practices for a Clean React Project».
React очень лоялен к тому, что и как мы пишем и как организуем свой код. Поэтому ответственность за поддержание чистоты и качества наших проектов несем только мы.
Сегодня поговорим о том, как это сделать, – о самых полезных практиках разработки на React.
1. Используйте JSX-сокращения
Использовать логические значения никогда не было так просто. Допустим, вам нужно управлять видимостью компонента Navbar
– с помощью пропса showTitle
:
Плохо
return ( <Navbar showTitle={true} /> );
Хорошо
return( <Navbar showTitle /> )
2. Используйте тернарные операторы
Отличный способ для выбора между двумя компонентами по некоторому условию – например, в зависимости от роли активного пользователя.
Плохо
const { role } = user; if(role === ADMIN) { return <AdminUser /> }else{ return <NormalUser /> }
Хорошо
const { role } = user; return role === ADMIN ? <AdminUser /> : <NormalUser />
3. Используйте преимущества объектных литералов
Если у вас выбор между тремя и более компонентами, тернарный оператор не подходит. В этом случае литералы объектов могут сделать код более читаемым – используйте их вместо сложных условий.
Плохо
const {role} = user switch(role){ case ADMIN: return <AdminUser /> case EMPLOYEE: return <EmployeeUser /> case USER: return <NormalUser /> }
Хорошо
const {role} = user const components = { ADMIN: AdminUser, EMPLOYEE: EmployeeUser, USER: NormalUser }; const Component = components[role]; return <Component />;
4. Используйте фрагменты
Нет никакого преимущества в использовании div
вместо Fragment
. Зачем вам нужен лишний элемент в виртуальном DOM?
Плохо
return ( <div> <Component1 /> <Component2 /> <Component3 /> </div> )
Хорошо
return ( <> <Component1 /> <Component2 /> <Component3 /> </> )
5. Не определяйте функцию внутри рендера
Старайтесь не смешивать логику и рендер внутри компонента.
Плохо
return ( <button onClick={() => dispatch(ACTION_TO_SEND_DATA)}> // NOTICE HERE This is a bad example </button> )
Хорошо
const submitData = () => dispatch(ACTION_TO_SEND_DATA) return ( <button onClick={submitData}> This is a good example </button> )
6. Используйте Memo
React.PureComponent
и Memo
могут значительно повысить производительность вашего приложения, позволяя избежать ненужного рендеринга.
Плохо
import React, { useState } from "react"; export const TestMemo = () => { const [userName, setUserName] = useState("faisal"); const [count, setCount] = useState(0); const increment = () => setCount((count) => count + 1); return ( <> <ChildrenComponent userName={userName} /> <button onClick={increment}> Increment </button> </> ); }; const ChildrenComponent =({ userName }) => { console.log("rendered", userName); return <div> {userName} </div>; };
Дочерний компонент должен отображаться только один раз, так как значение count не имеет к нему никакого отношения. И тем не менее он рендерится при каждом нажатии на кнопку.
Хорошо
Отредактируем немного ChildrenComponent
:
import React ,{useState} from "react"; const ChildrenComponent = React.memo(({userName}) => { console.log('rendered') return <div> {userName}</div> })
Теперь не имеет значения, сколько раз пользователь кликнет на кнопку, компонент отрендерится только при необходимости.
7. Перенесите CSS в JavaScript
Организовать CSS сложнее, чем JavaScript, но можно постараться.
Плохо
// CSS файл .body { height: 10px; } // JSX return <div className='body'> </div>
Хорошо
const bodyStyle = { height: "10px" } return <div style={bodyStyle}> </div>
8. Используйте деструктуризацию объектов
Одна из новейших возможностей JS сделает ваш код более читаемым.
Плохо
return ( <> <div> {user.name} </div> <div> {user.age} </div> <div> {user.profession} </div> </> )
Хорошо
const { name, age, profession } = user; return ( <> <div> {name} </div> <div> {age} </div> <div> {profession} </div> </> )
9. Строковые пропсы без фигурных скобок
Передать строковые данные проще, чем вы думаете.
Плохо
return( <Navbar title={"My Special App"} /> )
Хорошо
return( <Navbar title="My Special App" /> )
10. Удалите JS из JSX
Уберите весь код JavaScript из JSX-разметки, если он не служит какой-либо цели рендеринга или функциональности UI.
Плохо
return ( <ul> {posts.map((post) => ( <li onClick={event => { console.log(event.target, 'clicked!'); // <- THIS IS BAD }} key={post.id}>{post.title} </li> ))} </ul> );
Хорошо
const onClickHandler = (event) => { console.log(event.target, 'clicked!'); } return ( <ul> {posts.map((post) => ( <li onClick={onClickHandler} key={post.id}> {post.title} </li> ))} </ul> );
11. Строковые литералы
Используйте строковые литералы вместо громоздкой конкатенации строк.
Плохо
const userDetails = user.name + "'s profession is" + user.proffession return ( <div> {userDetails} </div> )
Хорошо
const userDetails = `${user.name}'s profession is ${user.proffession}` return ( <div> {userDetails} </div> )
12. Порядок импортов
Старайтесь импортировать модули в определенном порядке, чтобы сделать код более логичным.
Плохо
import React from 'react'; import ErrorImg from '../../assets/images/error.png'; import styled from 'styled-components/native'; import colors from '../../styles/colors'; import { PropTypes } from 'prop-types';
Хорошо
Эмпирическое правило заключается в следующем порядке импорта:
- сначала встроенные (build-in) модули;
- затем внешние;
- и наконец внутренние.
import React from 'react'; import { PropTypes } from 'prop-types'; import styled from 'styled-components/native'; import ErrorImg from '../../assets/images/error.png'; import colors from '../../styles/colors';
13. Используйте неявный return
Неявный возврат делает ваши функции изящнее. Но не злоупотребляйте этой фичей, она уместна только в простых функциях.
Плохо
const add = (a, b) => { return a + b; }
Хорошо
const add = (a, b) => a + b;
14. Именование компонентов
Всегда используйте PascalCase для имен компонентов и camelCase – для экземпляров.
Плохо
import reservationCard from './ReservationCard'; const ReservationItem = <ReservationCard />;
Хорошо
import ReservationCard from './ReservationCard'; const reservationItem = <ReservationCard />;
15. Зарезервированные имена свойств
Не используйте зарезервированные имена атрибутов для передачи пропсов, другие разработчики могут быть к этому не готовы.
Плохо
<MyComponent style="dark" /> <MyComponent className="dark" />
Хорошо
<MyComponent variant="fancy" />
16. Кавычки
Используйте двойные кавычки для атрибутов JSX и одинарные – для всего остального кода JavaScript.
Плохо
<Foo bar='bar' /> <Foo style={{ left: "20px" }} />
Хорошо
<Foo bar="bar" /> <Foo style={{ left: '20px' }} />
17. Именование пропсов
Всегда используйте camelCase для имен пропсов или PascalCase, если значение атрибута – это другой React-компонент.
Плохо
<Component UserName="hello" phone_number={12345678} />
Хорошо
<MyComponent userName="hello" phoneNumber={12345678} Component={SomeComponent} />
18. JSX в скобках
Если ваш компонент занимает больше, чем одну строчку, всегда оборачивайте его в скобки.
Плохо
return <MyComponent variant="long"> <MyChild /> </MyComponent>;
Хорошо
return ( <MyComponent variant="long"> <MyChild /> </MyComponent> );
19. Самозакрывающиеся теги
Если у вашего компонента нет дочерних элементов, используйте самозакрывающийся тег для улучшения читаемости.
Плохо
<SomeComponent variant="stuff"></SomeCompone
Хорошо
<SomeComponent variant="stuff" />
20. Подчеркивание в именах методов
Не используйте подчеркивание в любых внутренних методах.
Плохо
const _onClickHandler = () => { // do stuff }
Хорошо
const onClickHandler = () => { // do stuff }
21. Атрибут alt
Всегда устанавливайте атрибут alt для теги img и не используйте в нем слова image и picture. Альтернативный текст предназначен для скринридеров, которые и так объявляют элемент как изображение, зачем повторяться?
Плохо
<img src="hello.jpg" /> <img src="hello.jpg" alt="Picture of me rowing a boat"
Хорошо
<img src="hello.jpg" alt="Me waving hello" />
Заключение
Вот и все. Поздравляем, если вы зашли так далеко! Надеюсь, вы кое-что узнали из этой статьи.
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]