我有这个动作创作者:
export function getLevelsMap() {
const request = axios.get(`/api/levels`);
return {
type: GET_LEVELS_MAP,
payload: request
}
}
和这个减速器
import { GET_LEVELS_MAP } from '../actions';
export default function (state = null, action) {
switch (action.type) {
case GET_LEVELS_MAP:
return action.payload.levels;
default:
return state;
}
}
AJAX请求应该返回给我:
{
"levels": [
{
"_id": "5951b7f0600af549fb1d269a",
"name": "College",
"__v": 0,
"subjects": [
{
"_id": "594891db1dbdf635ca3019ab",
"name": "Maths",
"__v": 0
},
{
"_id": "5948920d1dbdf635ca3019ac",
"name": "Biology",
"__v": 0
}
...
请求确实有效(我已经用PostMan测试过了)
现在,我正在使用reducer和action:
连接我的组件function mapStateToProps(state) {
return {
levels: state.levels
}
};
export default connect(mapStateToProps, { getLevelsMap })(ChooseSubject);
我在componentDidMount方法中获取数据(调用操作):
componentDidMount() {
if (!this.props.levels) {
this.props.getLevelsMap();
}
}
并尝试使用reducer:
getSubjects(level) {
let levels = this.props.levels;
if (levels) {
for (var item of levels) {
if (item.name === level) {
return item;
}
}
}
return null;
}
这是我说我正在使用promise中间件的地方
const createStoreWithMiddleware = applyMiddleware(promise)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<Switch>
<Route path="/" component={HomePage} />
</Switch>
</BrowserRouter>
</Provider>
, document.querySelector('.root'));
但是,this.props.levels未定义...... PS:如果我硬编码(复制粘贴我在subject_reducer中从postMan获得的结果)来自AJAX请求的答案,那么一切都有效。
非常感谢您的非常感谢:)
答案 0 :(得分:2)
如前面的回答中所述,您的axios请求返回一个承诺而不是数据,因为您拥有的是未解决的承诺,从而导致您的道具不符合您的预期。
要回答你的问题,我认为你不需要使用redux-promise,而是使用redux-thunk。根据{{3}}答案,似乎redux-promise允许您的行为成为承诺,但redux-thunk允许您的行为成为您需要的功能。使用redux-thunk,您实际上可以解决承诺并将数据发送到您的减速器,而不像现在您的减速器正在承诺。
答案 1 :(得分:1)
您不是在等待axios完成通话。首先,我假设promise
内的applyMiddleware
类似于redux-thunk,你需要做异步操作。
您的动作创建者应如下所示:
export const getLevelsMap = () => {
return function(dispatch) {
axios.get(`/api/levels`)
.then(result => {
dispatch({
type: GET_LEVELS_MAP,
payload: result.data
});
})
.catch(err => console.log(err));
}
}
或者,使用async并等待:
export const getLevelsMap = () => async dispatch => {
try {
let response = await axios.get(`/api/levels`);
dispatch({
type: GET_LEVELS_MAP,
payload: result.data
})
} catch (err) {
console.log(err);
}
}