Дождитесь завершения двух API, запущенных разными компонентами, прежде чем запускать другой API - PullRequest
0 голосов
/ 26 сентября 2018

Основная навигация моего приложения должна вызывать API loggedInUser, чтобы позволить мне отображать различные ссылки в зависимости от того, вошел ли пользователь в систему. Этот API также используется во многих других частях моего приложения.Я использую Redux для управления состоянием, поэтому после запуска этого API я могу получить данные через хранилище Redux из любого подключенного компонента.

У меня также есть компонент ContentPage, который onEnter загружает содержимое через loadContentAPI.ContentPage - это компонент контейнера, который подключен к хранилищу Redux.

Наконец, у меня также есть API isFavourite, который принимает идентификатор и тип содержимого (возвращенный из loadContent API) и позволяет мнепереключать «любимую» кнопку на странице в зависимости от ответа.Этот API следует вызывать только после того, как оба API loadContent и loggedInUser сработали (мне не нужно беспокоиться об использовании API, если пользователь не вошел в систему).

Код нижеработает нормально, если API loggedInUser завершается до API loadContent, но не наоборот.Я изо всех сил пытаюсь придумать самый чистый способ сделать так, чтобы порядок, в котором возвращаемые данные API не влияли на логику.Если бы оба API запускались из одного и того же компонента, я мог бы сделать что-то вроде этого (поскольку я использую Fetch для вызовов API) ...

<Route
  path={'Content/:id'}
  component={ContentPage}
  onEnter={(nextState) => {
    // Needs to be synchronous
    store.dispatch(loadSession(nextState.params.id)).then(() =>
      store.dispatch(getLoggedInUser()),
    );
  }}
/>

... но поскольку они независимы, я не наденуНе знаю, как лучше подходить.

import React from 'react';
import { Route } from 'react-router';
import configureStore from './store/configureStore';

import { getLoggedInUser } from './actions/userActions';
import { loadContent } from './actions/contentActions';

import App from './components/App';
import ContentPage from './components/ContentPage';

export const store = configureStore();

export const routes = (
  <Route
    path={'/'}
    component={App}
    onEnter={() => store.dispatch(getLoggedInUser())}
  >
    <Route
      path={'Content/:id'}
      component={ContentPage}
      onEnter={nextState => store.dispatch(loadContent(nextState.params.id))}
    />
  </Route>
);

Это упрощенная версия моего компонента ContentPage.

class ContentPage extends Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.content.id !== nextProps.content.id) {
      // If the loggedInUser API hasn't yet fired then this if statement will never return true
      if (this.props.loggedInUser.id) {
        // I only want to fire this API if both the loggedInUser API and the loadContent API have both fired
        this.props.actions.isFavourite(nextProps.content.id, nextProps.content.type);
      }
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Итак, в темные времена я создал магазин электронной коммерции с одним скриптом Perl CGI для каждой страницы сайта.Каждый скрипт при запуске собирал необходимые ему данные (его «база данных» представляла собой набор файлов, которые он читал / писал, включая список продуктов с разделителями табуляции), а затем выписывал HTML-код для страницы и передавал его браузеру.Я думаю, что это одна из причин, по которой мне нравится React, она делает то же самое, но гораздо эффективнее!

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

Так что для вашего примера весь сайт должен быть отображаемым без сеанса, с сеансом, но без контента, с сеансом и контентом, но без фаворитов.Компоненты не должны ждать нужного контента.Если его нет, они отображают null, либо сообщение о загрузке, либо, возможно, данные-заполнители.Когда данные, на которые они опираются, изменяются, они соответствующим образом перерисовываются.

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

0 голосов
/ 26 сентября 2018

Почему бы просто не иметь переменную с именем stagesCompleted = 0 или что-то в этом роде, где каждый этап +=1 используется для каждого вызова API.Затем сделайте условный if(stagesCompleted == 2){} запуск вашего кода и сбросьте stagesCompleted var.таким образом, вы можете добавить или уменьшить количество действий, необходимых для его запуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...