Диспетчерское действие внутри Fetch

Я делаю асинхронный вызов, используя выборку, а затем пытаюсь установить состояние, отправляя действие на основе результата возвращенных данных json.

Я использую считыватель QR-кода для чтения кода, который передается моему методу didScan.

    didScan(code) {
      if (this.state.showCamera){
       this.props.pushNewRoute('finder');
       getAppointment(code)
       .then((appointment)=>{
         if (appointment.valid){
           this.props.appointmentDetails(appointment);
           this.props.resetRoute('summary');
         }else{
           this.props.resetRoute('error');
         }
       })
       .catch((error) => {
         this.props.resetRoute('error');
       });
       this.setState({showCamera: false});
     }
   }

Я использую react-redux для привязки своих действий к моим диспетчерам следующим образом:

      function bindActions(dispatch){
      return {
          resetRoute:(route)=>dispatch(resetRoute(route)),
          pushNewRoute:(route)=>dispatch(pushNewRoute(route)),
          appointmentDetails:(details)=>dispatch(appointmentDetails(details))
      }
  }

  export default connect(null, bindActions)(Scanner);

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

this.props.resetRoute('summary');

Ошибка

Возможное отклонение необработанного обещания{id:0} Редюсеры не могут отправлять действия

Ни один из моих редукторов не отправляет никаких действий, и код работает нормально, когда я вынимаю его из блока Promise .then().

Вот простой сервис получения getAppointment для полноты картины:

export function getAppointment(id:string) {
  return fetch('http://myurl/' + id + '/')
  .then((response) => response.json())
  .catch((error) => {
    console.error(error);
    return error;
  });
}

Любая помощь очень ценится.


person GavKilbride    schedule 31.10.2016    source источник


Ответы (1)


Я не уверен, какой у вас синтаксис для привязки действий, раньше его не видел. Вот пример кода, который я сделал для проекта, в котором я делаю запрос на получение, а затем устанавливаю ответ как состояние:

SearchBar.jsx (отправляет HTTP-запрос к Solr и возвращает объект JSON, а затем устанавливает этот объект в качестве состояния)

import React, {Component} from 'react';
import httpClient from 'axios';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {setResponse} from '../actions/index'

class SearchBar extends Component {

  constructor(props) {
    super(props);

    this.search = this.search.bind(this);
  }

  search() {
    let q = document.getElementById('searchbar').value;
    httpClient(`/search?q=${q}`, { baseURL: window.location.href })
      .then( resp => {
        console.log(resp);
        this.props.setResponse(resp);
      });
  }

  render() {
    return (
      <div>
        <input type='text' id='searchbar'/>
        <button onClick={this.search}>Search</button>
      </div>
    );
  }
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({setResponse: setResponse}, dispatch);
}

export default connect(null, mapDispatchToProps)(SearchBar);

Это действие:

export const setResponse = (res) => {
    return {
        type: 'RESPONSE_RECEIVED',
        payload: res
    }
};

Это редуктор:

export default function (state = null, action) {
    switch (action.type) {
        case 'RESPONSE_RECEIVED':
            return action.payload;
            break;
    }
    return state;
}

Который экспортируется в объединяющую функцию (правда редьюсер всего один атм):

import {combineReducers} from 'redux';
import ResponseReducer from './reducer-response';

const allReducers = combineReducers({
    response: ResponseReducer
});

export default allReducers;
person Jayce444    schedule 31.10.2016