Как исправить обещание, полученное вместо простого объекта после извлечения данных. все работает хорошо, но есть ошибка в консоли - PullRequest
0 голосов
/ 06 января 2019

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

mapDispatchToProps() in Connect(Home) must return a plain object. 
Instead received [object Promise]

Вот соответствующий код

/*************************************************/
// in the actions:

export function fetchPhotos(){
    const request = fetch("https://jsonplaceholder.typicode.com/photos")
        .then(response=>response.json())

    return request.then(json=>({type: 'FETCH_PHOTOS', payload:json})
}

/****************************************************/
//in the reducer:

const album=[] 

const albumReducer=(state=album,action)=> {
   switch (action.type){
   case "FETCH_ALBUMS": return (action.payload);
   case "FETCH_PHOTOS": return (action.payload);

   default: return state
}

export default albumReducer.

/****************************************************/
// in the component

const mapStateToProps=(state)=> {
    return {
        PhotoList:state.albumReducer
    }
}

const mapDispatchToProps=(dispatch)=> {
    return bindActionCreators(fetchPhotos,dispatch)
}

export default connect(mapStateToProps,mapDispatchToProps)(function PhotoList(props))

1 Ответ

0 голосов
/ 06 января 2019

Redux сам по себе не настроен для обработки асинхронных действий, таких как запрос на выборку данных. Redux делает это простым и целенаправленным. Приходит действие, редуктор генерирует новое состояние из этого действия, новое состояние используется для повторного рендеринга пользовательского интерфейса. Полоскание-повтор. Проблема здесь в том, что действие - fetchPhotos, которое является началом выборки. Редуктор не может генерировать новое состояние, которое включает фотографии, пока запрос не будет завершен, и все же Redux не собирается ждать. В конце концов, он получил действие и должен немедленно создать новое состояние.

К счастью, это не редкая проблема, и есть несколько решений, которые могут вам помочь. Двумя наиболее популярными являются redux-saga и redux-thunk

Redux Saga

  • Имеет довольно крутой кривой обучения.
  • Может (возможно) справиться с более сложными сценариями, чем примитивный
  • Использует генераторы

Redux Thunk

  • Очень легко читать и рассуждать о
  • Использует асинхронное / ожидание / обещание

Я рекомендую взглянуть на обе библиотеки и посмотреть, в какую из них вам легче погрузиться. Оба могут решить вашу дилемму. Я думаю, что redux-thunk может быть самым простым (и самым быстрым) решением для вас.

Дополнительные лакомые кусочки По сути, обе эти библиотеки помогают вам структурировать асинхронный процесс последовательно. Поэтому вместо того, чтобы генерировать одно действие fetchPhotos, вы разбиваете его на шаги. fetchPhotosStart, fetchPhotosComplete, fetchPhotosFailed. Таким образом, ваш редуктор может обрабатывать каждый шаг независимо, генерируя новое состояние и не застревая в ожидании обещания. Когда обещание в конечном итоге разрешается, вы запускаете действие завершения или сбоя, чтобы обновить хранилище еще раз с данными или сообщением об ошибке.

Я считаю это чрезвычайно полезным, поскольку я могу установить isLoading при запуске запроса и отображать любые нужные мне счетчики или индикаторы выполнения. Когда запрос завершается, я устанавливаю isLoading на false, а также вставляю свои данные в хранилище. В случае сбоев я могу установить сообщение об ошибке в магазине и показать любой интерфейс обратной связи об ошибке, который может иметь мое приложение.

Итак, используя ваш пример, очень упрощенный пример будет:

// in the actions:
// remove fetchPhotos since we only care about photos data
export function fetchPhotosSuccess(photos) {
    return {
        type: 'FETCH_PHOTOS_SUCCESS',
        payload: photos
    }
}

// in the component
class MyComponent extends React.Component {
    fetchPhotos() {
        const self = this;
        fetch("https://jsonplaceholder.typicode.com/photos")
            .then(response => response.json())
            .then(json => self.props.fetchPhotosSuccess(photos))
    }
}

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators(fetchPhotosSuccess, dispatch)
}

Надеюсь, это поможет!

...