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

Основная настройка

Мое приложение сочетает интерфейс React/Redux с серверной частью API Rails. Интерфейс создается с помощью create-react-app, а серверная часть создается с помощью rails new my_app --api.

В процессе разработки внешний интерфейс запускается с сервером разработки Webpack на localhost:3000, а сервер API работает на localhost:3001. Это создает проблему CORS (обмен ресурсами между источниками), поскольку приложение React пытается загрузить ресурсы из другого источника. Чтобы решить эту проблему, я настраиваю сервер разработки Webpack для прокси-запросов к серверу API. Механизм иллюстрируется диаграммой из статьи о Fullstack React:
![](https://www.fullstackreact.com/assets/images/articles/cra-with-server/flow-diagram-2. png)

При этом каждый раз, когда React отправляет запрос API, запрос отправляется на сервер разработки Webpack по адресу localhost:3000.

Приложение React

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

Home отображает компонент Map, который представляет собой настроенные карты GoogleMaps, импортированные с помощью react-google-maps. Сам компонент Map отображает SearchBarи MyMarkerClusterкомпоненты. Оба эти компонента представляют собой два альтернативных способа взаимодействия пользователя с местами, в которых Твиттер имеет тенденции:
*MyMarkerCluster, указывает каждое доступное местоположение с помощью маркера на карте, который может выбрать пользователь;
*SearchBar позволяет пользователю напрямую искать местоположение с помощью раскрывающегося списка данных, который сужает параметры поиска по мере ввода пользователем.

Как только пользователь выбирает маркер или вводит поиск, ShowPage отображает результаты. Он отображает три дочерних компонента: 1) NavBar в верхней части страницы, чтобы пользователь мог вернуться на страницу Home, 2) TrendList, отображающий тенденции местоположения, и 3) TweetList, отображающий твиты определенной тенденции, когда последний нажимается.

Для каждого Tweet пользователь может подписаться на пользователя, сделать ретвит, а также лайкнуть твит. Каждое из этих пользовательских взаимодействий инициирует запрос на выборку к API Rails, который затем выполняет соответствующий запрос к API Twitter.

Реагировать/сокращать

Я использую Redux для управления состоянием моего приложения React.
Состояние, сохраненное в хранилище Redux, выглядит следующим образом:

{
 places = [],
 placeQuery: {
 trends: [],
 query: {
 woeid: 0,
 name: ‘’
 }
 },
 trendQuery: {
 isFetching: false,
 query: ‘’,
 tweets: []
 }
}

Я оборачиваю компонент App в Provider, чтобы компоненты контейнера имели доступ к хранилищу после connect-ed как такового:

connect(mapStateToProps, mapDispatchToProps)(containerComponent)

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

API Rails

Сервер API имеет шесть конечных точек, каждая из которых взаимодействует с API Twitter через гем Twitter для выполнения действий запроса:

get api/trending/available_places : возвращает JSON всех мест, где доступны тренды;

get api/trending/location/:tweet_query : возвращает JSON всех твитов данного тренда;

get api/follow/:user_scree_name : делает запрос к Twitter API, чтобы подписаться на пользователя;

post api/retweet/:tweet_id : отправляет запрос в Twitter API на ретвит твита;

post api/favorite/:tweet_id: делает запрос к Twitter API, чтобы лайкнуть твит.