Методы выборки данных с помощью React

841
Методы выборки данных с помощью React
Методы выборки данных с помощью React

Методы выборки данных с помощью React. Многие веб-приложения полагаются на данные из внешних источников, чтобы обеспечить хорошее взаимодействие с пользователем. Знание различных методов выборки данных в React позволит вам принимать обоснованные решения о наилучшем варианте использования вашего приложения.

В этой статье мы рассмотрим различные методы получения данных в веб-приложениях, созданных с помощью React. Мы сосредоточимся на использовании хуков, представленных в React 16.8, для извлечения данных из популярного JSON Placeholder API для отображения в приложении React.

Начало работы. Методы выборки данных с помощью React

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

# using npm
npx create-react-app project_name

# using yarn
yarn create react-app project_name

Команда выше загружает приложение React с помощью инструмента create-react-app.

Перейдите в каталог проекта

cd project_name

Запуск приложения

# using npm
npm start

# using yarn
yarn start

Fetch API

Fetch API -интерфейс, который позволяет выполнять сетевые запросы в веб-приложениях. Он очень похож на XMLHttpRequest (XHR), но улучшает его, облегчая выполнение асинхронных запросов. Он также лучше обрабатывает ответы.

С API fetch относительно легко начать работу. Ниже приведен пример использования API fetch для получения данных:

fetch('http://jsonplaceholder.typicode.com/posts')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log(error));

В приведенном примере мы получаем данные из JSON Placeholder API и выводим их в консоль. Функция fetch принимает в качестве аргумента местоположение ресурса и возвращает promise в качестве ответа. Мы используем функцию response.json() для преобразования ответа, полученного от API, в JSON. Ответ также может быть преобразован в другие форматы, если это необходимо вашему приложению. Если promise отклоняется из-за ошибки, выполняется блок catch.

Чтобы интегрировать API fetch в приложение React, которое мы создали ранее, перейдите в каталог src и создайте директорию components, в этой папке будут храниться все компоненты React. Создайте файл Notes.js в каталоге компонентов, этот файл отвечает за отображение данных, полученных от внешнего API. Откройте файл и вставьте в него приведенный ниже код

import React from 'react';
const Notes = ({ data }) => {
  return (
    <div>
      <ul>
        {data && data.map((item, index) => <li key={index}>{item.title}</li>)}
      </ul>
    </div>
  );
};
export default Notes;

Создайте другой файл под названием FetchDemo.js и вставьте в него приведенный ниже код

import React, { useState, useEffect } from 'react';
import Notes from './Notes';
const FetchDemo = () => {
  const [notes, setNotes] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  const fetchData = () => {
    fetch('http://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json())
      .then((data) => {
        setIsLoading(false);
        setNotes(data);
      })
      .catch((error) => {
        setIsLoading(false);
        setIsError(true);
        console.log(error);
      });
  };
  useEffect(() => {
    fetchData();
  }, []);
  if (isLoading) {
    return <div>Loading...</div>;
  }
  return (
    <div>
      <h1>Fetch Example</h1>
      {notes && <Notes data={notes} />}
      {isError && <div>Error fetching data.</div>}
    </div>
  );
};
export default FetchDemo;

В этом компоненте мы создали функцию fetchData, которая отвечает за получение списка заметок из JSON Placeholder. Ответ, полученный из данных, сохраняется в состоянии notes, которое передается как props  {notes && <Notes data={notes} />} компоненту Notes, созданному нами ранее для отображения заметок. Если при получении данных возникла ошибка, мы изменяем состояние isError и выводим пользователю сообщение об ошибке  {isError && <div>Error fetching data.</div>}. У нас также есть состояние isLoading, которое мы используем для отображения сообщения о загрузке для пользователя, пока мы ждем ответа от сделанного сетевого запроса.

Функция fetchData вызывается в хуке useEffect, который запускается один раз при установке компонента (подробнее об  useEffects  читайте здесь).

Перейдите к файлу App.js  и замените существующий код на код ниже

import React from 'react';
import FetchDemo from './components/FetchDemo';
function App() {
  return (
    <div className="App">
      <h1>Posts</h1>
      <FetchDemo />
    </div>
  );
}
export default App;

Здесь мы сделали следующее: импортировали созданный нами компонент FetchDemo и отобразили его в компоненте App. Сохраните файл и посмотрите результаты в браузере, результаты должны быть похожи на скриншот ниже:

Методы выборки данных с помощью React
Методы выборки данных с помощью React

Воспроизведение сеансов с открытым исходным кодом

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

Воспроизведение сеансов с открытым исходным кодом
Воспроизведение сеансов с открытым исходным кодом

Используйте OpenReplay — это удобное для разработчиков воспроизведение сессий с открытым исходным кодом.

Axios

Axios — это легкий HTTP-клиент на основе Promise для браузера и Node.js. Он похож на Fetch API, поскольку также используется для выполнения сетевых запросов. В отличие от fetch, он преобразует все ответы в JSON.

Ниже приведен пример использования API fetch для получения данных

axios.get('http://jsonplaceholder.typicode.com/posts')
  .then(response => console.log(response))
  .catch(error => console.log(error));

Этот пример очень похож на fetch, поскольку Axios также основан на promise. Основное отличие, как упоминалось ранее, заключается в том, что нам не нужно преобразовывать ответы в JSON, поскольку Axios делает это автоматически. Некоторые другие возможности Axios включают:

  • Перехват запроса и ответа
  • Преобразование данных запроса и ответа
  • Отмена запросов
  • Поддержка защиты от XSRF на стороне клиента

Чтобы интегрировать Axios в приложение React, откройте терминал в корневом каталоге приложения и выполните приведенный ниже код

# using npm
npm install axios

# using yarn
yarn add axios

Приведенные выше команды устанавливают Axios в приложение React.

Создайте файл с именем AxiosDemo.js в каталоге компонентов и вставьте в него приведенный ниже код

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Notes from './Notes';
const AxiosDemo = () => {
  const [notes, setNotes] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  const fetchData = () => {
    axios
      .get('http://jsonplaceholder.typicode.com/posts')
      .then((response) => {
        setIsLoading(false);
        setNotes(response.data);
      })
      .catch((error) => {
        setIsLoading(false);
        setIsError(true);
        console.log(error);
      });
  };
  useEffect(() => {
    fetchData();
  }, []);
  if (isLoading) {
    return <div>Loading...</div>;
  }
  return (
    <div>
      <h1>Using Axios</h1>
      {notes && <Notes data={notes} />}
      {isError && <div>Error fetching data.</div>}
    </div>
  );
};
export default AxiosDemo;

Приведенный выше код показывает, как получить данные с помощью Axios. Первым шагом был импорт библиотеки Axios, мы установили import axios из ‘axios’ Библиотека Axios затем используется в функции fetchData, где мы делаем запрос на получение данных из библиотеки JSON Placeholder. Полученный ответ мы сохраняем в состоянии заметок, и если мы сталкиваемся с какой-либо ошибкой, мы выдаем пользователю соответствующее сообщение об ошибке.

Перейдите в файл App.js и замените существующий код на приведенный ниже код

import React from 'react';
import FetchDemo from './components/FetchDemo';
import AxiosDemo from './components/AxiosDemo';
function App() {
  return (
    <div className="App">
      <AxiosDemo />
    </div>
  );
}
export default App;

В компоненте App мы визуализировали компонент AxiosDemo. Сохраните и откройте приложение в браузере

В компоненте App мы визуализировали компонент AxiosDemo.
В компоненте App мы визуализировали компонент AxiosDemo.

Получение данных с помощью Async/Await

«async/await» упрощает асинхронное программирование в JavaScript. Он предоставляет возможность писать обещания чисто и лаконично и убирает все блоки .then(). В «async/await» есть две части:

  • async: async — это ключевое слово, помещаемое перед объявлением функции, которое заставляет функцию возвращать promise. Например: async function hello() { return «hello»; } hello().then(console.log) //hello
  • await: Ключевое слово await используется в функции async и заставляет функцию ожидать разрешения promise. let value = await promise;

«async/await» — это не столько техника получения данных, сколько лучший способ использования существующих техник работы с данными, упомянутых ранее. Мы можем рефакторизовать существующий сетевой вызов Axios с использованием promises в предыдущем разделе из кода ниже

axios
  .get('http://jsonplaceholder.typicode.com/posts')
  .then((response) => {
    setIsLoading(false);
    setNotes(response.data);
  })
  .catch((error) => {
    setIsLoading(false);
    setIsError(true);
    console.log(error);
  });

на

try {
  const response = await axios.get(
    'http://jsonplaceholder.typicode.com/posts'
  );
  setIsLoading(false);
  setNotes(response.data);
} catch (error) {
  setIsLoading(false);
  setIsError(true);
  console.log(error);
}

Это делает код менее сложным и более читабельным.

Пользовательские хуки для получения данных

Согласно документации React:

Пользовательский хук — это функция JavaScript, имя которой начинается с «use» и которая может вызывать другие хуки.

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

Мы создадим хук useAxios, который забирает логику получения данных из компонента AxiosDemo, созданного нами ранее. Перейдите в каталог src и создайте каталог hooks. Теперь перейдите в каталог hooks и создайте файл useAxios.js. Откройте файл и вставьте приведенный ниже код:

import { useState, useEffect } from 'react';
import axios from 'axios';

const useAxios = (url) => {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  const fetchData = async () => {
    try {
      const response = await axios.get(url);
      setIsLoading(false);
      setData(response.data);
    } catch (error) {
      setIsLoading(false);
      setIsError(true);
      console.log(error);
    }
  };
  useEffect(() => {
    fetchData();
  }, []);
  return { isLoading, isError, data };
};
export default useAxios;

В приведенном выше коде мы извлекли необходимые состояния и логику получения данных из компонента AxiosDemo, мы также добавили параметр url. Это означает, что мы можем использовать этот хук в любом компоненте, которому нужно получить данные из любого места, не обязательно JSON Placeholder, и вернуть ответ обратно компоненту, которому нужны данные. Методы выборки данных с помощью React.

Теперь давайте отрефакторим наш компонент AxiosDemo, чтобы использовать хук useAxios. Откройте файл AxiosDemo.js и замените существующий код на приведенный ниже:

import React from 'react';
import useAxios from '../hooks/useAxios';
import Notes from './Notes';

const AxiosDemo = () => {
  const { isLoading, isError, data: notes } = useAxios(
    'http://jsonplaceholder.typicode.com/posts'
  );
  if (isLoading) {
    return <div>Loading...</div>;
  }
  return (
    <div>
      <h1>Using Axios</h1>
      {notes && <Notes data={notes} />}
      {isError && <div>Error fetching data.</div>}
    </div>
  );
};

export default AxiosDemo;

Мы импортировали хук useAxios в компонент AxiosDemo. Мы используем хук, передавая аргумент url:

const { isLoading, isError, data: notes } = useAxios("http://jsonplaceholder.typicode.com/posts");

После получения данных хук возвращает объект, который мы деструктурировали для использования в компоненте AxiosDemo.

Concurrent Mode и Suspense

Concurrent mode и Suspense — это экспериментальные функции, представленные в React 16.6 для обработки получения данных в приложениях React. Чтобы начать работу с concurrent mode, откройте терминал в корне вашего приложения и выполните приведенный ниже код:

# using npm
npm install react@experimental react-dom@experimental

# using yarn
yarn add react@experimental react-dom@experimental

Перейдите к файлу index.js и замените существующий код на приведенный ниже:

import ReactDOM from 'react-dom';

// If you previously had:
//
// ReactDOM.render(<App />, document.getElementById('root'));
//
// You can opt into Concurrent Mode by writing:

ReactDOM.unstable_createRoot(
  document.getElementById('root')
).render(<App />);

Concurrent mode — это набор новых функций, которые помогают приложениям React оставаться отзывчивыми в ожидании результата операции, включая Suspense — компонент, позволяющий задать состояние загрузки в ожидании завершения выполнения какого-либо действия кода.

// show a loading message while waiting for notes to be loaded
const notes = fetchData()
<Suspense fallback={<div>Loading...</div>}>
  <Notes data={notes} />
</Suspense>

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

if (isLoading) {
  return <div>Loading...</div>;
}

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

Для ясности, Concurrent mode и Suspense все еще являются экспериментальными и не должны использоваться в приложениях, готовых к продакшн. Также стоит отметить, что Suspense — это не механизм получения данных, а скорее способ отложить рендеринг компонентов, пока вы ждете недостающих данных. Дэн Абрамов показал отличную демонстрацию работы Suspense, посмотрите ее здесь.

Заключение по Методы выборки данных с помощью React

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

# Методы выборки данных с помощью React