Подтвердить что ты не робот

Где я беру исходные данные с сервера в приложении React Redux?

Я начал изучать React/Redux и наткнулся на что-то, что, вероятно, очень простой вопрос. Ниже приведены фрагменты из моего приложения с удаленным кодом для простоты.

Мое состояние описывается массивом сайтов, который по умолчанию пуст. Позже редуктор будет иметь LOAD_SITES действие для загрузки другого набора сайтов всякий раз, когда пользователь разбивает страницы на другую страницу, но пока ничего не делает. Реагирование начинается с рендеринга PublishedSitesPage, который затем отображает PublishedSitesBox, который затем перебирает данные и отображает отдельные сайты.

Что я хочу сделать, так это сделать все с пустым массивом по умолчанию и тем временем инициировать обещание "загрузить сайты с сервера", и как только оно будет разрешено, отправьте LOAD_SITES действие. Каков наилучший способ сделать этот звонок? Я думал о любом конструкторе PublishedSitesBox или, возможно, componentDidMount. Но не уверен, что это сработает - моя забота состоит в том, что я создам бесконечный цикл таким образом, который будет продолжать повторную визуализацию. Наверное, я мог бы предотвратить этот бесконечный цикл каким-то образом, имея некоторый другой параметр состояния по строкам "hasRequestedInitialData". Еще одна идея, которую я имел, заключается в том, чтобы просто выполнить это обещание сразу после выполнения ReactDOM.render(). Каков наилучший и самый чистый способ сделать это?

export default function sites(state = [], action) {
  switch (action.type) {
    default:
      return state;
  }
}
...

const publishedSitesPageReducer = combineReducers({
  sites
});

ReactDOM.render(
  <Provider store={createStore(publishedSitesPageReducer)}>
    <PublishedSitesPage />
  </Provider>,
  this.$view.find('.js-published-sites-result-target')[0]
);

...

export default function PublishedSitesPage() {
  return (
    <PublishedSitesBox/>
  );
}

...

function mapStateToProps(state) {
  return { sites: state.sites };
}

const PublishedSitesBox = connect(mapStateToProps)(({sites}) => {
  // render sites
});
4b9b3361

Ответ 1

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

(Неважно, начинаете ли вы запускать асинхронный вызов до или после вызова ReactDOM.render, обещание будет работать в любом случае)

Что-то вроде этого:

var store = createStore(publishedSitesPageReducer);

someAsyncCall().then(function(response) {
  store.dispatch(someActionCreator(response));
});

ReactDOM.render(
  <Provider store={store}>
    <PublishedSitesPage />
  </Provider>,
  this.$view.find('.js-published-sites-result-target')[0]
);

Ваши компоненты React являются потребителями вашего магазина, но нет правила, что они должны быть ТОЛЬКО потребителями вашего магазина.

Ответ 2

Здесь есть яркий пример: Facebook Tutorial

Что касается бесконечного цикла, как только ваш массив больше не пуст, очистите интервал. Это должно предотвратить цикл.