无法弄清楚"错误:操作必须是普通对象。使用自定义中间件进行异步操作。"

时间:2018-01-20 19:57:53

标签: react-redux

我使用React和Redux构建应用程序以请求并随后从API显示电影信息。在控制台中,我可以获取所请求的数据,但除此之外我遇到了错误 - "错误:操作必须是普通对象。使用自定义中间件进行异步操作。"

到目前为止,这是我的代码..

搜索组件:

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

class SearchBar extends Component {
  constructor(props) {
    super(props);

    this.state = { term: '' };

    this.onInputChange = this.onInputChange.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

  onInputChange(e) {
    this.setState({ term: e.target.value });
  }

  onFormSubmit(event) {
    event.preventDefault();
    this.props.fetchMovie(this.state.term); 
    this.setState({ term: '' });
  }

  render() {
    return (
      <div>
        <form onSubmit={this.onFormSubmit} className="input-group">
          <input
            placeholder="Search by movie title, actor, or genre"
            className="form-control"
            value={this.state.term}
            onChange={this.onInputChange}
          />
          <span className="input-group-btn">
            <button type="submit" className="btn btn-secondary">
              Submit
            </button>
          </span>
        </form>
        <br />
      </div>
    );
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchMovie }, dispatch);
}

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

动作...

import axios from 'axios';

const API_KEY = '449a384f';

export const FETCH_MOVIE = 'FETCH_MOVIE';

let movies = [];

export function fetchMovie(term) {
  const request = axios
    .get(`http://www.omdbapi.com/?s=${term}&apikey=${API_KEY}`)
    .then(response => {
      movies = response.data;
      response.json = movies;
    })
    .catch(error => console.log(error));

  return {
      type: FETCH_MOVIE,
      payload: request,
    };
}

...减速器

import { FETCH_MOVIE } from '../actions/index';

export default function(state = null, action) {
  switch (action.type) {
    case FETCH_MOVIE:
      return [action.payload.data, ...state];
  }
  return state;
}

... CombineReducer

import { combineReducers } from 'redux';
import MovieReducer from './movie_reducer';

const rootReducer = combineReducers({
  movie: MovieReducer,
});

export default rootReducer;

贮存......

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
// import ReduxThunk from 'redux-thunk';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';

import './index.css';
import App from './App';
import Login from './components/login/login';
import reducers from './reducers/reducer';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import { findDOMNode } from 'react-dom';
import $ from 'jquery';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <BrowserRouter>
      <Switch>
        <Route path="/Login" component={Login} />
        <Route path="/" component={App} />
      </Switch>
    </BrowserRouter>
  </Provider>,
  document.querySelector('#root')
);

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

Vanilla Redux要求您在动作创建者中返回纯JavaScript对象。每当你需要执行异步操作时,你需要引入像redux-thunk或redux-promise这样的中间件来拦截返回的对象并执行额外的工作,以便最终返回一个普通的JavaScript对象。

您正在尝试使用redux-promise,但您返回的内容并未导致调用中间件。您的fetchMovie()方法返回一个包含Promise的普通对象。为了使用redux-promise,该方法需要返回一个Promise。

来自documentation

createAction('FETCH_THING', async id => {
  const result = await somePromise;
  return result.someValue;
});

答案 1 :(得分:0)

原因可能是你试图在行动中将承诺归还给减速器。

您正在使用thunk,因此您始终可以从动作创建者发送

export const fetchMovie = term => dispatch => axios
  .get(`http://www.omdbapi.com/?s=${term}&apikey=${API_KEY}`)
  .then(response => {
    dispatch({
      type: FETCH_MOVIE,
      payload: response,
    });
  })
  .catch(error => console.log(error));