5 концептів які зроблять з вас кращого React розробника

5 концептів які зроблять з вас кращого React розробника
Переклад 8 хв. читання

Дізнайтеся, як використовувати передові концепцти React, це допоможе вам стати кращим розробником React.

Індивідуальні хуки (custom hooks)

Як ви вже знаєте, хуки — це нове доповнення в React 16.8, яке дозволить вам використовувати стан та інші функції React без написання класу чи компонента. Створення власних хуків — це чудовий спосіб винесення логіки компонентів у функції, які можна повторно використовувати та тестувати незалежно.

import { useEffect, useState } from 'react';

export const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(res => res.json)
      .then(setData)
      .catch(setError)
      .then(() => setLoading(false))
  }, [url]);
  
  return [data, isLoading, error];
};

function Profile() {
  const [data: profile, isLoading, error] = useFetch('/profile');
  return (
    <>
      {loading && <Spinner />}
      {data && <Profile data={data} />}
      {error && <Toast error={error} />}
    </>
  );
}

Хоча це і простий приклад, але він показує, як асинхронну логіку отримання даних можна повторно використовувати для різних викликів API у вашій програмі.

Докладніше про те, як і писати повторно використовуваний код за допомогою хуків React.

Контекст

React Context — це функція, яка дозволяє передавати дані через ієрархію компонентів без необхідності передавати параметри до окремих компонентів вручну. Контекст особливо корисний для обміну даними, які вважаються «глобальними» в усій програмі, як-от облікові дані користувача, тематика, мова тощо.

import { useState, useContext, createContext } from 'react';

const themeContext = createContext();

const useTheme = () => useContext(themeContext);

const ThemeProvider = ({ theme, ...rest }) => {
  const [theme, setTheme] = useState(theme);
  return ;
}

const Toolbar = () => {
  const [theme, setTheme] = useTheme();
  return (
    <>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light' )}
      ...
    </>
  );
}

const App = () => (
  <ThemeProvider theme="light">
    <Toolbar />
    <Routes />
  </ThemeProvider>
);

У простому прикладі вище ви можете легко змінити тему на «світлу» або «темну» , використовуючи хук useTheme , і зміна пошириться на всі компоненти в ієрархії, оскільки значення надається контекстом.

Портали

React Portals — це спосіб перенести дочірні компоненти у вузол DOM, який існує поза ієрархією батьківських компонентів. Незважаючи на те, що портали можна змонтувати в будь-якому місці дерева DOM, вони поводяться як звичайні діти React у всіх інших аспектах. Контексти також працюватимуть з порталами, як і з будь-якими іншими компонентами React. Типові варіанти використання порталів включають модальні вікна, спливаючі меню, підказки тощо, де вам потрібно монтувати компоненти на більш високому рівні в дереві DOM.

const Modal = ({ title, content }) => {
  const containerDiv = document.getElementById('containerDiv');

  return ReactDOM.createPortal(
    <>
      <h1>{title}</h1>
    <>, 
    containerDiv
  );
}

const App = () => {
  const [loggedIn] = useUser();

  return (
    <>
      <Article />
      {!loggedIn && <Modal title="login">...</Modal>}
    </>
  );
}

Компоненти вищого порядку

Компонент вищого порядку React (HOC) — це шаблон для повторного використання компонентної логіки. HOC — це функції, які беруть компонент як аргумент і повертають новий компонент. Якщо типові компоненти перетворюють props у вузли в DOM, компонент вищого порядку перетворює компонент в інший компонент.

const withSearch = (Component) => ({ list, ...rest }) => {
  const [search, setSearch] = useState('');
  const matches = useMemo(() => (
    list.filter(item => item.indexOf(search) > -1;
  ), [search]);
  
  return (
    <>
      <SearchInput onChange={setSearch} />
      <Component list={matches} {...rest} />
    </>
  );
}

// Assume a simple list component MyList can be turned into a searchable
// list component using the withSearch HOC
const SearchableMyList = withSearch(MyList);

Напруження

Напруження (Suspense) — це функція, яка дозволяє вашому компоненту декларативно чекати, поки щось завантажиться, перш ніж його можна буде відтворити. Suspense можна використовувати для очікування завантаження деякого коду за допомогою React.Lazy у поєднанні з React.Suspense, або, починаючи з React 18.0.0, його можна використовувати для очікування завантаження деяких асинхронних даних. Нижче я коротко розповім про ці два основні варіанти використання;

Читайте також: Вступ до React

Ліниве завантаження коду

Розбиття коду — це техніка, при якій веб-застосунок «розбивається» на частини для підвищення швидкості завантаження. Ідея полягає в тому, що спочатку ви завантажуєте лише сценарії та ресурси, які негайно потрібні для відображення певної сторінки. Решта скриптів та активів завантажуються ліниво, коли це необхідно.

const ArticlePage = React.lazy(() => import('./ArticlePage'));

// Fallback to a skeleton while the ArticlePage is loading
<Suspense fallback={<ArticleSkeleton />}>
  <ArticlePage />
</Suspense>

У наведеному вище прикладі сценарії та ресурси для ArticlePage не завантажуються, доки їх не потрібно буде відобразити.

Отримання даних за допомогою Suspense

Отримання даних із затримкою є новою функцією з React 18.0.0, хоча і була випущена як експериментальна функція в попередніх версіях.

Типовий підхід до отримання даних за допомогою React полягав у тому, щоб почати відтворення компонентів, а потім, використовуючи хук useEffect, кожен з цих компонентів може викликати деяку логіку отримання даних, наприклад, виклик API, після чого оновлення стану та рендерінг.

Цей підхід часто призводить до «водоспадів», коли вкладені компоненти ініціюють вибірку лише тоді, коли батьківські компоненти готові, як показано в коді нижче.

const Article = ({ data }) => {
  const [suggestions, setSuggestions] = useState(null);
  useEffect(() => fetch(`/suggestions/${article.title}`).then(setSuggestions), []);
  return suggestions ? <Suggestions data={suggestions} />
}

const ArticlePage = ({ id }) => {
  const [article, setArticle] = useState(null);
  useEffect(() => fetch(`/article/${id}`).then(setArticle), []);
  return article ? <Article data={article} />
}

Часто багато з цих операцій можна навіть паралельно виконувати.

Із suspense ми не чекаємо відповіді, ми просто запускаємо асинхронні запити і починаємо рендеринг негайно. Потім React спробує відобразити ієрархію компонентів. Якщо щось не вдається відобразити, через відсутні дані, воно просто повернеться до будь-якого резервного варіанту, визначеного в обгортці Suspense.

// This is not a Promise. It's a special object from our Suspense integration.
const initialArticle = fetchArticle(0);

function Articles() {
  const [article, setArticle] = useState(initialArticle);
  
  return (
    <>
      <button onClick={() => { setArticle(fetchArticle(article.id + 1)) } }>
        Next
      </button>
      <ArticlePage article={article} />
    </>
  );
}

function Article({ article }) {
  return (
    <Suspense fallback={<Spinner />}>
      <ArticleContent article={article} />
      <Suspense fallback={<h1>Loading similar...</h1>}>
        <Similar similar={article} />
      </Suspense>
    </Suspense>
  );
}

function ArticleContent({ article }) {
  const article = article.content.read();
  return (
    <>
      <h1>{article.title}</h1>
      ...
    </>
   );
}

У наведеному вище прикладі стаття відображатиметься лише під час завантаження, а в іншому випадку — спіннер, тоді як подібні статті відображатимуться лише тоді, коли вони завантажені. За лаштунками функції fetchArticle відбувається якась магія, про яку я розповім у наступній публікації. Слідкуйте за оновленнями! 📻

На цьому 5 концепцій, які зроблять вас кращим розробником React . Сподіваюся, вам сподобалося читати і дізналися щось нове! 👍

Джерело: 5 Concepts That Will Make You a Better React Developer
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація