我正在构建一个简单的应用程序,以从API URL检索一些食谱。 我正在阅读Thunk的文档以实现它,但我不明白如何设置异步获取请求。 奇怪的是,如果我在console.log中将传递到减速器中的动作肯定检索到正确的对象(切碎鸡肉的食谱列表)。 当我将动作传递给reducer时,它将引发错误:
“未处理的拒绝(错误):给定操作“ FETCH_RECIPES”,减速器“ recipes”返回未定义。要忽略某个动作,必须显式返回先前的状态。如果希望此减速器不保留任何值,则可以返回null而不是未定义。”
我的动作创建者是否有任何错误? API调用正确完成了吗?
商店
import React from 'react';
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import SearchBar from './components/App';
import thunk from 'redux-thunk';
import 'bootstrap/dist/css/bootstrap.css';
import rootReducer from './reducers';
const store = createStore(rootReducer, applyMiddleware(thunk));
render(
<Provider store={store}>
<SearchBar />
</Provider>,
document.getElementById('root')
)
组件
import React, { Component } from 'react';
import { connect } from 'react-redux';
import './App.css';
import { Button } from 'reactstrap';
import { Form } from 'reactstrap';
import { bindActionCreators } from 'redux';
import {fetchRecipe } from '../actions';
class SearchBar extends Component {
constructor(props) {
super(props)
this.state = { term: ''};
this.typeRecipe = this.typeRecipe.bind(this)
this.onFormSubmit = this.onFormSubmit.bind(this);
}
onFormSubmit(e) {
e.preventDefault()
this.props.fetchRecipe(this.state.term)
}
typeRecipe(e) {
this.setState({term: e.target.value});
}
render() {
return (
<div className="SearchBar">
<Form onSubmit={this.onFormSubmit}>
<input type='text'
value={this.state.term}
placeholder='ciao'
onChange={this.typeRecipe}
/>
<br/>
<Button id='ciao' className='btn-success'>Submit</Button>
</Form>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchRecipe }, dispatch);
}
export default connect(null, mapDispatchToProps)(SearchBar);
动作创建者
import axios from 'axios';
export const FETCH_RECIPES = 'FETCH_RECIPES';
const API_KEY = 'xxx';//not the real one.
export function fetchRecipe() {
const request = axios.get(`http://food2fork.com/api/search?key=${API_KEY}&q=shredded%20chicken`);
return (dispatch) => {
request.then(({data}) =>{
dispatch({ type: FETCH_RECIPES, payload: data})
})
}
}
减速器
import { FETCH_RECIPES } from '../actions';
export default function (state = {}, action) {
switch(action.type) {
case FETCH_RECIPES:
const newState = action.payload.data;
return newState;
default:
return state
}
}
combineReducer(索引)
import recipeReducer from '../reducers/recipes_reducer';
import { combineReducers } from 'redux';
const rootReducer = combineReducers({
recipes: recipeReducer
});
export default rootReducer;
答案 0 :(得分:1)
Mistake在减速器的return语句中。
export default function (state = {}, action) {
switch(action.type) {
case FETCH_RECIPES:
const newState = {...state, data : action.payload.data};
return newState;
default:
return state
}
}
在这里,我们将data
键添加到reducer状态,可以在容器中使用它来访问此键:
export default connect((state)=>{
var mapStateToProps = {};
if(state.recipes.data) {
mapStateToProps['recipes'] = state.recipes.data
}
return mapStateToProps;
}, mapDispatchToProps)(SearchBar);
和配方数据将以this.props.recipes
的形式提供。