Методы выборки данных с помощью 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. Сохраните файл и посмотрите результаты в браузере, результаты должны быть похожи на скриншот ниже:
Воспроизведение сеансов с открытым исходным кодом
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. Сохраните и откройте приложение в браузере
Получение данных с помощью 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