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

Posted

技术标签:

【中文标题】REACT 如何使用 Redux 和 Axios(使用 promise 中间件)发出 AJAX 请求?【英文标题】:REACT How to make AJAX requests with Redux and Axios (with promise middleware)? 【发布时间】:2017-11-30 20:24:57 【问题描述】:

我有这个动作创建者:

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 测试过)

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

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 获得的结果复制粘贴到 subject_reducer 中),一切正常。

非常感谢您的帮助:)

【问题讨论】:

我不完全确定您了解Redux 的工作原理。您正在调用一个简单地返回操作的函数,而不是将其分派到您的商店。如果您使用带有 axios 的 promise 中间件,您的有效负载将隐藏在 promise 后面,您将无法访问它 this.props.level 不会在 reducer 函数中定义 @m_callens,谢谢你的回答。 promise 中间件确实返回了一个 promise,但是一旦 get 请求得到响应,它就会用数据重新渲染组件(我认为是这样) 【参考方案1】:

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

要回答你的问题,我认为你不需要使用 redux-promise,而是使用 redux-thunk。根据this 的回答,似乎 redux-promise 允许您的操作成为承诺,但 redux-thunk 允许您的操作成为您需要的功能。使用 redux-thunk,您实际上将能够解决 Promise 并将数据发送到您的 reducer,不像现在您的 reducer 只是得到一个 Promise。

【讨论】:

感谢您的回答!那我一定会试试的:)【参考方案2】:

您无需等待 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);
    

【讨论】:

感谢您的回答。我已经在某处看到了这个答案。但我没有得到的是,在我遵循的教程中,他们不使用那些异步操作...... redux-promise 应该处理它(我不是使用 inx redux-thunk 而是 redux-promise)。它应该按照我尝试的方式工作;)

以上是关于REACT 如何使用 Redux 和 Axios(使用 promise 中间件)发出 AJAX 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 axios 添加到 react-redux-universal-hot-example 入门套件?

使用 React、Redux 和 Axios 处理异步请求?

如何使用 react-redux 存储令牌并在多个 axios 请求中使用它?

如何在客户端处理 CORS 错误(React-Redux-Axios)

如何从服务器端 express/mongo/mongoose 中的 URL,客户端的 axios/react/redux 中获取参数 ID

React + redux + axios + thunk,等待interceptors.response 刷新token