REACT 如何使用 Redux 和 Axios(使用 promise 中间件)发出 AJAX 请求?

REACT How to make AJAX requests with Redux and Axios (with promise middleware)?

我有这个动作创建器:

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 请求应该 return 我这个 :

{
"levels": [
{
  "_id": "5951b7f0600af549fb1d269a",
  "name": "College",
  "__v": 0,
  "subjects": [
    {
      "_id": "594891db1dbdf635ca3019ab",
      "name": "Maths",
      "__v": 0
    },
    {
      "_id": "5948920d1dbdf635ca3019ac",
      "name": "Biology",
      "__v": 0
    }
  ...

请求确实有效(我用 PostMan 测试过)

现在,我将我的组件与减速器和动作连接起来:

function mapStateToProps(state) {
return {
    levels: state.levels
}
};

export default connect(mapStateToProps, { getLevelsMap })(ChooseSubject);

我正在 componentDidMount 方法中获取数据(调用操作):

  componentDidMount() {
    if (!this.props.levels) {
        this.props.getLevelsMap();
    }
}

并尝试使用减速器:

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:如果我对 AJAX 请求的答案进行硬编码(复制粘贴我从 postMan 得到的结果到 subjects_reducer),一切正常。

非常感谢您的帮助:)

您不是在等待 axios 完成调用。首先,我假设 applyMiddleware 内部的 promise 类似于 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));
    }
}

或者,使用异步和等待:

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);
    }
}

如之前的回答所述,您的 axios 请求返回的是承诺而不是数据,您所拥有的是未解决的承诺,因此导致您的道具不是您所期望的。

为了回答您的问题,我认为您不需要使用 redux-promise,而是使用 redux-thunk。基于 答案,似乎 redux-promise 允许您的操作成为承诺,但 redux-thunk 允许您的操作成为您需要的功能。使用 redux-thunk,您实际上能够解决承诺并将数据发送到您的减速器,这与现在您的减速器刚刚获得承诺不同。