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