我使用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')
);
感谢您的帮助!
答案 0 :(得分:0)
Vanilla Redux要求您在动作创建者中返回纯JavaScript对象。每当你需要执行异步操作时,你需要引入像redux-thunk或redux-promise这样的中间件来拦截返回的对象并执行额外的工作,以便最终返回一个普通的JavaScript对象。
您正在尝试使用redux-promise,但您返回的内容并未导致调用中间件。您的fetchMovie()
方法返回一个包含Promise的普通对象。为了使用redux-promise,该方法需要返回一个Promise。
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));