Как использовать React Context API с функциональным компонентом

В этой статье мы создадим небольшое приложение на React, используя Hackernews API.

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

Введение в Context API

Контекстный API - это API, предлагаемый React для помощи в управлении состоянием. Он предлагает нам те же функции, что и redux.

Если бы мы должны были передать значение состояния от родительского компонента другому дочернему компоненту, нам пришлось бы передавать данные через props. Но этот процесс может усложниться по мере увеличения количества компонентов. Чтобы упростить задачу обмена данными между компонентами, нам пришлось использовать некоторые сторонние библиотеки управления состоянием. Но теперь React предлагает нам Context API, который помогает нам управлять состоянием.

Теперь давайте воспользуемся API для создания небольшого приложения. Наше приложение будет очень простым. Мы будем использовать Context API для создания приложения. Наш проект будет выглядеть так:

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

А теперь приступим.

Давайте создадим приложение для реагирования. Для этого нам нужно ввести следующую команду в нашем терминале внутри нашего основного рабочего каталога:

npx create-react-app .

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

npm i bootstrap axios

Мы будем использовать бутстрап для стилизации и аксиом для запроса данных.

Теперь, когда мы установили пакет, перейдем к реализации проекта.

Давайте откроем файл App.js внутри каталога src. Затем напишите следующие строки кода:

Вы можете видеть в приведенном выше коде, что мы выполнили некоторые операции импорта. Мы импортировали два компонента: NewsList и Description. В ближайшее время мы будем работать над этими компонентами. Вы можете видеть в строке 6, мы импортировали NewsState. Затем мы использовали его как оболочку в строке 12. Это NewsState - глобальное состояние, которое может использоваться любыми дочерними по отношению к нему компонентами. Это означает, что компоненты NewsList и Description, которые являются компонентами в строках 14 и 15, имеют доступ к NewsState. Скоро мы будем работать над NewsState.

Теперь займемся государством. Для этого давайте создадим каталог с именем context внутри каталога src. Создайте файл с именем types.js внутри каталога context. Затем создайте папку с именем Новости внутри каталога context. Затем создайте три файла с именами NewsContext.js, NewsState.js, NewsReducer.js внутри src / context / News. каталог. Это должно сделать структуру папок каталога context примерно такой:

Теперь, когда мы создали эти файлы, давайте откроем файл NewsContext.js и напишем следующие строки кода:

import { createContext } from "react";

const NewsContext = createContext();

export default NewsContext;

Здесь мы импортировали createContext. Функция createContext заключается в создании контекста, как следует из названия.

С помощью createContext мы создали контекст и сохранили его в константе NewsContext. Затем мы экспортировали файл NewsContext.

Теперь давайте откроем NewsState.js и напишем следующие строки кода:

В приведенном выше коде мы видим, что первые несколько строк - это всего лишь импорт. В строке 1 мы импортировали React и useReducer. Затем в строках 4 и 5 мы импортировали соответственно NewsContext и NewsReducer. Мы будем работать над NewsReducer в ближайшее время. Точно так же мы импортировали GET_NEWS и GET_DESCRIPTION в строке 6 из types.js. Мы поговорим об этих типах через некоторое время.

В строке 8 мы создали NewsState. Мы создали initialState в строке 9. После этого, в строке 14, мы использовали useReducer. useReducer принимает два аргумента. Первым аргументом должен быть reducer, который в нашем случае NewsReducer. Второй аргумент - это initialState. Этот useReducer предоставляет нам state и dispatch. state предоставляет нам значения состояния, как следует из названия. Функция dispatch помогает нам отправлять полученные данные в нашу функцию-редуктор.

После этого в строке 16 у нас есть функция с именем getNews. Эта функция помогает нам получать новости из конечной точки Rest API в строке 18. Если возникает какая-либо ошибка при извлечении данных, мы записываем ее в консоль в строке 23. В строке 21 мы использовали функцию dispatch. Функция dispatch помогает отправить наши данные редуктору. Редуктор в конечном итоге изменит наше состояние. Скоро будем работать над редукторами.

Давайте внимательно рассмотрим функцию dispatch. Функция dispatch в строке 21 принимает объект, содержащий payload и type в качестве параметров. payload должны быть данными, которые нам нужно хранить в состоянии. type принимает имя типа, которым в данном случае является GET_NEWS.

В строке 27 мы видим функцию getDescription. Эта функция помогает нам получать описания определенных новостей. Мы написали код для отправки запроса в строке 29 с использованием id. Затем в строке 32 мы отправили наши payload и type с их значениями как data и GET_DESCRIPTION соответственно. Если возникает какая-либо ошибка, мы записываем ее в консоль в строке 34.

Теперь взглянем на строки с 39 по 48. Там мы использовали NewsContext.Provider. Этот NewsContext.Provider действует как оболочка для созданного нами контекста. Помните, что мы создали NewsContext в файле NewsContext.js. Вы также можете вспомнить, что мы использовали эту оболочку как NewsState в файле App.js.

Теперь поговорим о NewsContext.Provider. NewsContext.Provider принимает опору value. value должен быть объектом, содержащим пару "ключ-значение" наших состояний и функций. value доступен каждому потомку этого провайдера. Затем в строке 47 вы можете увидеть, что мы написали код для рендеринга дочерних компонентов с помощью {props.children}.

Теперь, когда мы разобрались с кодом, написанным в NewsState.js, давайте откроем файл NewsReducer.js и напишем следующие строки кода:

Вы можете видеть в строке 1, мы импортировали типы GET_NEWS и GET_DESCRIPTION. Затем мы экспортировали нашу функцию редуктора. Мы можем видеть, что функция редуктора находится в строке с 3 по 20. Функция редуктора принимает в качестве аргумента state и payload. Затем в строке 4 мы создали две константы payload и type и сохранили значения action.payload и action.type. Помните, что action - это объект, который мы получили от функции dispatch в NewsState.js.

В строках с 6 по 19 мы использовали switch case. Мы проверяем type действия. Если тип GET_NEWS, мы деструктурируем наше начальное состояние, а затем меняем значение news в нашем состоянии на payload. Если тип GET_DESCRIPTION, мы деструктурируем наше состояние, а затем меняем значение activeNews в нашем состоянии на payload.

Давайте теперь откроем файл types.js и напишем следующие строки кода:

export const GET_NEWS = "GET_NEWS";
export const GET_DESCRIPTION = "GET_DESCRIPTION";

Основная причина, по которой мы создали types.js, заключается в том, что, как вы видели, нам нужны имена типов для различных действий. Эти имена типов используются в нашем редукторе и состоянии. Мы могли бы жестко запрограммировать тип в обоих файлах, но при этом мы можем столкнуться с некоторыми проблемами. Если в названии типа произойдет какая-либо опечатка, мы можем столкнуться с ошибкой, которую будет трудно отладить.

Теперь давайте создадим каталог component внутри основного каталога проекта. Затем давайте создадим два файла Description.js и NewsList.js внутри каталога component. В результате наша директория component должна выглядеть так:

Давайте теперь откроем файл NewsList.js и напишем следующие строки кода:

Мы видим, что первые несколько строк - это импорт. Мы импортировали useContext и useEffect в строке 1. Мы импортировали наш newsContext в строке 3.

В строке 6 мы использовали useContext. useContext принимает наш контекст, который мы создали. В данном случае наш контекст newsContext. Затем мы сохранили контекст как NewsContext.

Теперь давайте посмотрим на строки с 8 по 10. Здесь мы использовали useEffect. То, как мы использовали useEffect, действует как ComponentDidMount в компонентах на основе классов. Когда компонент монтируется, мы выполняем код NewsContext.getNews(). Помните, что мы добавили функцию getNews в качестве нашего value в NewsContext.Provider в файле NewsState.js. Этот getNews извлекает новости из API и затем добавляет их в наше состояние.

Теперь посмотрим на строку 15. Мы написали код для условного рендеринга. Если NewsContext.news существует, мы отображаем массив news и визуализируем его в DOM. Помните, что news - это значение состояния, которое мы определили в NewsContext.Provider внутри файла NewsState.js.

В строке 20 мы использовали прослушиватель событий onClick. Когда на него нажимают, мы просим NewsContext получить описание этого конкретного идентификатора новости, используя NewsContext.getDescription(news.id). Помните, что getDescription - это функция, которую мы добавили в value в NewsContext.Provider в файле NewsState.js.

Теперь, когда мы поработали с файлом NewsList.js, давайте откроем файл Description.js и напишем следующие строки кода:

Давайте посмотрим, что здесь происходит. Мы сделали здесь импорт. В строке 1 мы импортировали useContext и React. В строке 3 мы импортировали newsContext.

Вы можете видеть в строке 14, мы использовали условный рендеринг. Если activeNews существует, мы написали код для отображения значений, представленных в activeNews. В строке 16 мы написали код для отображения заголовка новости с помощью activeNews.title. Затем в строке 19 мы написали код для отображения имени автора с помощью activeNews.user. Затем, в строке 20, мы написали код, показывающий, как давно статья была опубликована с использованием activeNews.time_ago. Затем в строке 21 мы написали код для отображения количества комментариев с помощью activeNews.comment.length. Точно так же в строке 27 мы написали код для отображения URL-адреса статьи / новости с использованием activeNews.url. Мы также использовали тег a, чтобы направить нашего пользователя на этот URL. Кроме того, в строке 32 мы написали код для отображения точек с использованием activeNews.points.

На этом мы завершили наш мини-проект и узнали, как использовать Context API в функциональных компонентах.

Я рекомендую вам ознакомиться с документацией React, чтобы узнать больше о контекстном API.

JavaScript на простом английском языке

Понравилась эта статья? Если да, то получите больше похожего контента, подписавшись на наш канал на YouTube в Decoded!