Исходное состояние Async React-Redux Redux-Thunk

Используя React, Redux, Redux-thunk я хочу получить начальное состояние через запрос к серверу (вызов API), но не могу заставить его работать.

Что у меня так далеко:

var Redux = require('redux');
var carReducer = require('./reducers/cars');
var thunk = require('redux-thunk').default;

var initialState = require('./reducers/initialState');

var rootReducer = Redux.combineReducers({
    cars: carReducer
});

module.exports = Redux.applyMiddleware(thunk)(Redux.createStore)(rootReducer, initialState.loadInitial());

Это мое первоначальное создание магазина. Мой InitialState выглядит так:

var $ = require('jquery');

module.exports = {
    loadInitial: loadInitial
};

function loadInitial() {
    return {
        cars: [
            {}
        ]
    }
}

Когда я пытаюсь превратить этот loadInitial в $.get('api/...'), Redux говорит мне, что мне нужно начальное состояние, чтобы оно работало.

В моем редукторе у меня есть метод загрузки:

function updateReducer(state, action) {
    switch (action.type) {
        case 'load':
            return action.data;
        case 'update':
            return updateCars(action.data, state);
        default:
            return action.data || initialState.loadInitial().cars;
    }
};

Но опять же, если я использую - по умолчанию - асинхронный вызов, он, похоже, не работает.

На самом деле я хочу, чтобы мой магазин был инициализирован тем, что происходит из базы данных. Это необходимо для моего HandsonTable, так как я передаю свойства в таблицу и, как она у меня есть, она будет отображать мне только одну строку, потому что мое начальное состояние имеет только один объект.

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

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

Ответ 1

Вы можете задать ему пустое начальное состояние (пустой объект или, возможно, просто сообщение о загрузке), и когда ваш вызов API возвращается, вы можете обновить состояние, и ваш компонент, как следствие, будет перерисован с новыми данными. Другая вещь, которую вы можете сделать, это не инициализировать ваш компонент, пока вызов не вернется с вашими данными.

ИЗМЕНЕНО, ЧТОБЫ ВКЛЮЧИТЬ ПРИМЕР

В одном из ваших методов жизненного цикла вашего компонента (возможно, даже в getInitialState):

getInitialState: function() {
  var oThis = this;

  $.get({
    url: 'api...',
    success: function (...) {
      oThis.setState({...data returned by server});
    }
  });

  return {};
}

Или что-то вроде этого:

$.get({
  url: 'api...',
  success: function (...) {
    var oStore;

    // oStore = response from server

    ReactDOM.render(
      <ReactRedux.Provider store={oStore}>
        <MyComponent/> 
      </ReactRedux.Provider>
      , document.getElementById()
    );
  }
});

Ответ 2

Для исходного состояния redux вы не можете передать значение async, поэтому вам нужно передать некоторый статический пустой объект (например, в вашем примере) и вызвать действие, чтобы получить начальное состояние с сервера и заменить ваше состояние. Чтобы упростить весь этот процесс, вы можете использовать сокращенное async начальное состояние middleware