5 лучших практик для React-разработчика

5 лучших практик для React-разработчика Изучение

Есть много способов структурировать код так, чтобы он был удобочитаемым, и у каждого есть свой способ добраться до него. Возникает вопрос : а есть ли лучший способ сделать это?

В этой статье я расскажу о пяти наиболее распространенных лучших практиках для разработчиков React. React был разработан таким образом, чтобы его можно было настраивать именно так, как вам нужно — он не самоуверенный! Так что, если эти пять сценариев «передовой практики» вам не подходят, вы можете найти свой собственный подход. Я надеюсь, что вы поймете что-то не так, как сейчас думают другие.

Руководство по безопасности React.js

Справочная организация

В документации React упоминается, что существует два основных способа организации приложения React: группировка по функциям или маршрутам и группировка по типу файла. Главное здесь — не задумываться.

Если вы начинаете с небольшого приложения, вы можете органично организовать свой код по ходу работы так, чтобы это работало для вас. Помните, что React не самоуверен, поэтому все зависит от вас, как все устроено. Пока у вас есть логическое объяснение того, как организованы файлы, на самом деле это не имеет большого значения.

Однако, поскольку в документации React упоминаются эти две стратегии организации, давайте посмотрим на каждую, чтобы увидеть, как они структурированы. Допустим, у нас есть приложение для электронной коммерции, в котором есть пользователь, список продуктов, подробная страница продукта, корзина для покупок и процесс оформления заказа.

Как это можно разложить по функциям?

Группировка по функциям

Корневой каталог здесь — это srcкаталог, который является одним из двух базовых каталогов в вашем приложении React (общая папка является другой). В srcкаталоге у нас будут основные файлы App.jsи index.jsфайлы в корне папки. Затем у нас будут вложенные каталоги для каждой функции вашего приложения.

Ваш ход может варьироваться в зависимости от того, как все организовано: у него может быть больше каталогов, меньше каталогов или даже дальнейшее вложение в компоненты, стили и тестирование.

src/
App.js
App.css
App.test.js
index.js
global/ ⇐ items that are in common with entire application
  AppContext.js
  ThemeContext.js
  UserContext.js
  Button.js
cards/
  index.js
  Cards.css
  Cards.js
  Card.css
  Card.js
  Card.test.js
detailed-product/
    DetailedProduct.css
  DetailedProduct.js
  DetailedProduct.test.js
checkout/
  ReviewOrder.css
  ReviewOrder.js
  ReviewOrder.test.js
  ShoppingCart.css
  ShoppingCart.js
  ShoppingCart.test.js
user/
  index.js
  User.css
  User.js
  User.test.js

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

Группировка по типу файла

Корневой каталог по-прежнему остается srcкаталогом. Все, что клиент увидит на экране, по-прежнему находится в этой папке. Как и прежде, мы будем держать App.jsи index.jsфайл в корневой директории и затем каталоги, представляющие собой составные части приложения: компоненты, контекст, CSS, крючки и тесты.

src/
App.js
index.js
components/
  App.css
  Card.js
  Cards.js
  ConfirmationPage.js
  DetailedProduct.js
  Footer.js
  Navbar.js
  ReviewOrder.js
  Settings.js
  ShoppingCart.js
  User.js
context/
  AppContext.js
  ThemeContext.js
  UserContext.js
css/
  Card.css
  Cards.css
  ConfirmationPage.css
  DetailedProduct.css
  Footer.css
  Navbar.css
  ReviewOrder.css
  Settings.css
  ShoppingCart.css
  User.css
hooks/
  useAuth.js
  useAxios.js
  …other custom hooks
tests/
  App.test.js
  Card.test.js
  Cards.test.js
  ConfirmationPage.test.js
  DetailedProduct.test.js
  Footer.test.js
  Navbar.test.js
  ReviewOrder.test.js
  Settings.test.js
  ShoppingCart.test.js
  User.test.js

Как и раньше, способ настройки вашего проекта зависит от вашего приложения и от того, как вы хотели бы его реализовать. Основная структура здесь зависит от типа файла и не более того. В конечном итоге ваша файловая структура должна быть такой, чтобы по ней было легко ориентироваться. Как вы это сделаете, зависит от вас.

Компоненты и разделение проблем

До React Hooks было довольно легко определить, что считалось компонентом класса с отслеживанием состояния и функциональным компонентом представления. Некоторые разработчики также называют их «умными» компонентами и «глупыми» компонентами. Умные компоненты, конечно же, несут логику состояния и обработки, а глупые компоненты — это те, которые просто принимают данные им реквизиты.

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

В конечном итоге вам и / или вашей команде решать, как построить свой шаблон проектирования, но передовая практика имеет тенденцию хранить логику и локальные компоненты с отслеживанием состояния отдельно от статических компонентов.

Состояние обработки и свойства

Поток данных в приложении React очень важен. Есть два способа работы с данными: использовать состояние или передавать состояние в качестве свойств. Давайте посмотрим на лучшие практики.

Состояние

При обработке состояния, будь то глобально в контекстном API или локально, оно не должно изменяться напрямую путем переназначения свойства в состоянии с новым значением:

 addOne = () => { //Don’t use this!!!!
   this.state.counter += 1;
 }

Вместо этого при обработке состояния в компонентах класса используйте this.setState()метод для обновления состояния.

import React from «react»;
import «./styles.css»;
class Counter extends React.Component{
 constructor(props) {
   super(props);
   this.state = {
     counter: 0
   }
 }
 addOne = () => {
   this.setState({counter: this.state.counter + 1})
 }
 subtractOne = () => {
   this.setState({counter: this.state.counter — 1});
 }
 reset = () => {
   this.setState({ counter: 0 });
 }
 render() {
   return (
     <div className=»App»>
       <h1>Simple React Counter</h1>
       <h2>{this.state.counter}</h2>
       <button onClick={this.addOne}> + </button>
       <button onClick={this.reset}> Reset </button>
       <button onClick={this.subtractOne}> — </button>
     </div>
   );
 }
}
export default Counter;

При использовании React Hooks вы будете использовать то, что вы называете для своего setметода:

import React, { useState } from «react»;
import «./styles.css»;
export default function App(){
 const [ counter, setCounter ] = useState(0);
 const addOne = () => {
   setCounter(counter + 1)
 }
 const subtractOne = () => {
   setCounter(counter — 1);
 }
 const reset = () => {
   setCounter(0);
 }
   return (
     <div className=»App»>
       <h1>Simple React Counter</h1>
       <h2>{counter}</h2>
       <button onClick={subtractOne}> — </button>
       <button onClick={reset}> Reset </button>
       <button onClick={addOne}> + </button>
     </div>
   );
}

Реквизит

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

Хотя код, безусловно, работал бы, если бы вы передавали реквизиты многим поколениям, он подвержен ошибкам, и за потоком данных может быть трудно следить. Лучше всего, если вам нужно предоставить детям доступ к состоянию на несколько поколений ниже, вы должны создать своего рода шаблон проектирования для глобального управления состоянием с помощью Redux или Context API (с Context API в настоящее время более простой и предпочтительный способ).

Абстракция

React процветает благодаря возможности многократного использования. Когда говорят о лучших практиках React, часто используется термин абстракция. Абстракция означает, что есть части большого компонента или приложения, которые можно убрать, превратить в их собственный функциональный компонент, а затем импортировать в более крупный компонент. Если сделать компонент настолько простым, насколько это возможно, часто так, чтобы он служил только одной цели, это увеличивает вероятность повторного использования кода.

В созданном выше простом приложении счетчика есть возможности абстрагироваться от некоторых элементов из компонента приложения. Кнопки можно абстрагировать в отдельный компонент, в который мы передаем метод и метку кнопки в качестве свойств.

Заголовок и заголовок приложения также могут входить в отдельные компоненты. Компонент приложения может выглядеть примерно так после того, как мы все абстрагировали:

import React, { useState } from «react»;
import { Button } from «./Button»;
import { Display } from «./Display»;
import { Header } from «./Header»;
import «./styles.css»;
export default function App(){
  const addOne = () => {
   setCounter(counter + 1)
 }
 const subtractOne = () => {
   setCounter(counter — 1);
 }
 const reset = () => {
   setCounter(0);
 }
 const initialState = [
   {operation: subtractOne, buttonLabel:»-«},
   {operation: reset, buttonLabel: «reset»},
   {operation: addOne, buttonLabel: «+»}
 ]
 const [ counter, setCounter ] = useState(0);
 const [ buttonContents,  ] = useState(initialState)
    return (
     <div className=»App»>
       <Header header=»Simple React Counter»/>
       <Display counter={counter}/>
       {buttonContents.map(button => {
         return (
           <Button key={button.operation + button.buttonLabel} operation={button.operation} buttonLabel={button.buttonLabel} />
         )
       })}
     </div>
   );
}

Основная цель абстракции — сделать дочерние компоненты как можно более общими, чтобы их можно было повторно использовать любым способом, который вам нужен. Компонент приложения должен содержать только всю информацию, относящуюся к приложению, и отображать или возвращать только более мелкие компоненты.

Соглашение об именовании

В React есть три основных соглашения об именах, которые следует рассматривать как лучшую практику.

1. Компоненты должны быть PascalCase- также с заглавной буквы в camelCase и названы в соответствии с их функцией, а не конкретной функцией приложения (на случай, если вы измените ее позже).
2. Элементы, которым требуются ключи, должны быть уникальными, неслучайными идентификаторами(такими как отдельные карты или записи в CardDeck или List). Лучше всего не использовать только индексы для ключей. Допустимо назначение клавиш, состоящее из конкатенации двух различных свойств объекта.

Основное назначение ключа — хранить основную информацию, чтобы React мог понять, что изменилось в приложении.

key={button.operation + button.buttonLabel} 

3. Методы должны быть в camelCase и названы в зависимости от их функции,а не для конкретного приложения. По тем же причинам, по которым компоненты находятся в PascalCase, методы должны называться в соответствии с их назначением, а не их особенностями в приложении.

Подведение итогов

В этой статье мы рассмотрели пять лучших практик для разработки на React. Во многих из этих случаев речь идет больше о том, что работает для вас и вашей команды, а не о том, что конкретно считается «наилучшей практикой».

Помните: React не волнует, как вы передаете данные — его волнует только то, что вы делаете.

Разработчики, которые позже редактируют и читают ваш код, должны будут иметь возможность расшифровать и улучшить ваш вклад.

Читайте также:  15 законов UX, которые должен знать каждый дизайнер
Оцените статью
bestprogrammer.ru
Добавить комментарий