Redux-thunk: ответ API остается в ожидании - PullRequest
0 голосов
/ 02 сентября 2018

Я пытаюсь разработать приложение, которое показывает фотографии из Unsplash с заданным ключевым словом. Мне удалось получить конкретные фотографии с помощью unsplash.js. В моих действиях у меня есть несколько создателей действий:

export const fetchPhotos = () => ({
  type: FETCH_PHOTOS
});

export const receivePhotos = term => {
  const unsplash = new Unsplash({
    applicationId:
      "id",
    secret: "secret",
    callbackUrl: "callback"
  });
  console.log(term);

  const response = unsplash.search
    .photos(term, 1, 20)
    .then(toJson)
    .then(json => json)
    .then(json => json)

  console.log(response.then(results => results));
  return {
    type: RECEIVE_PHOTOS,
    payload: response
  };
}

export const unsplash = (term) => dispatch => {
  console.log(term);
  dispatch(fetchPhotos());

  setTimeout(() => {
    dispatch(receivePhotos(term));
    console.log("dispatching")
    return Promise.resolve();
  }, 1000)
}

Мои редукторы затем:

const initialState = {
  isFetching: false,
  sortDirection: null,
  sortKey: null,
  items: []
}

export default function(state = initialState, action) {
  switch (action.type) {
    case FETCH_PHOTOS:
    console.log(state, "Fetch photos reducer");
      return {
        ...state,
        isFetching: true
      };
    case RECEIVE_PHOTOS:
      console.log("Receive photos reducer", action.payload)
      return {
        ...state,
        isFetching: false,
        items: action.payload
      };
    case SET_SORT:
      return {
        ...state,
        sortKey: action.sortKey,
        sortDirection: action.sortDirection
      };
    default:
      return state;
  }
}

Однако, поскольку создатель действия receivePhotos вызывает API, у меня есть обещание, которое необходимо выполнить, чтобы все приложение работало. Мой редуктор фотографий извлекает консоль, регистрирующую действие, затем появляется Обещание, однако оно всегда находится в ожидании. Затем мой создатель действия receivePhotos отправляет редуктор, и я вижу, что это Обещание:

enter image description here

Как я могу выполнить это обещание?

1 Ответ

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

В приведенном ниже коде вы назначаете обещание для response, затем console.log это обещание, а затем возвращаете действие с payload, установленным для этого обещания.

const response = unsplash.search
  .photos(term, 1, 20)
  .then(toJson)
  .then(json => json)
  .then(json => json)

console.log(response.then(results => results));
return {
  type: RECEIVE_PHOTOS,
  payload: response
};

dispatch(receivePhotos(term)); затем отправляет это действие, по-прежнему с полезной нагрузкой в ​​качестве обещания. возможно это сработало бы, если бы у вас было промежуточное программное обеспечение, способное справиться с этим.

Это использование диспетчеризации предполагает, что вы используете избыточный поток. В этом случае вы должны сделать то же самое с receivePhotos, включить вызов fetchPhotos и прекратить действие unsplash.

const unsplashClient = new Unsplash({
  applicationId:
    "id",
  secret: "secret",
  callbackUrl: "callback"
});

export const receivePhotos = term => dispatch => {
  dispatch(fetchPhotos());
  return unsplashClient.search
    .photos(term, 1, 20)
    .then(toJson)
    .then(json => dispatch({
      type: RECEIVE_PHOTOS,
      payload: json
    });
}

В конце я хотел бы предложить немного рефакторинга действий и (связанных редукторов), таких как:

const unsplashClient = new Unsplash({
  applicationId:
    "id",
  secret: "secret",
  callbackUrl: "callback"
});

export const fetchingPhotos = payload => ({
  type: FETCHING_PHOTOS, payload
});

export const setPhotos = payload => ({
  type: SET_PHOTOS, payload
});

export const fetchPhotos = term => dispatch => {
  dispatch(fetchingPhotos(true));
  return unsplashClient.search
    .photos(term, 1, 20)
    .then(toJson)
    .then(json => {
      dispatch(setPhotos(json));
      dispatch(fetchingPhotos(false));
    });
}
...