Redux-Thunk - 异步动作创建者承诺和链接不起作用
Posted
技术标签:
【中文标题】Redux-Thunk - 异步动作创建者承诺和链接不起作用【英文标题】:Redux-Thunk - Async action creators Promise and chaining not working 【发布时间】:2018-06-14 16:09:49 【问题描述】:我正在尝试调度一个动作。我找到了一些操作的工作示例,但没有我的那么复杂。
你能给我一个提示吗?我做错了什么?
我正在使用 TypeScript,最近删除了所有类型并尽可能简化了我的代码。
我正在使用 redux-thunk 和 redux-promise,像这样:
import save from 'redux-localstorage-simple';
import thunkMiddleware from 'redux-thunk';
import promiseMiddleware from 'redux-promise';
const middlewares = [
save(),
thunkMiddleware,
promiseMiddleware,
];
const store = createStore(
rootReducer(appReducer),
initialState,
compose(
applyMiddleware(...middlewares),
window['__REDUX_DEVTOOLS_EXTENSION__'] ? window['__REDUX_DEVTOOLS_EXTENSION__']() : f => f,
),
);
组件 - Foo 组件:
import actionFoo from 'js/actions/actionFoo';
import React, Component from 'react';
import connect from 'react-redux';
class Foo
constructor(props)
super(props);
this._handleSubmit = this._handleSubmit.bind(this);
_handleSubmit(e)
e.preventDefault();
this.props.doActionFoo().then(() =>
// this.props.doActionFoo returns undefined
);
render()
return <div onClick=this._handleSubmit/>;
const mapStateToProps = () => ();
const mapDispatchToProps =
doActionFoo: actionFoo,
;
export Foo as PureComponent ;
export default connect(mapStateToProps, mapDispatchToProps)(Foo);
动作 - actionFoo:
export default () => authCall(
types: ['REQUEST', 'SUCCESS', 'FAILURE'],
endpoint: `/route/foo/bar`,
method: 'POST',
shouldFetch: state => true,
body: ,
);
操作 - AuthCall:
// extremly simplified
export default (options) => (dispatch, getState) => dispatch(apiCall(options));
动作 - ApiCall:
export default (options) => (dispatch, getState) =>
const endpoint, shouldFetch, types = options;
if (shouldFetch && !shouldFetch(getState())) return Promise.resolve();
let response;
let payload;
dispatch(
type: types[0],
);
return fetch(endpoint, options)
.then((res) =>
response = res;
return res.json();
)
.then((json) =>
payload = json;
if (response.ok)
return dispatch(
response,
type: types[1],
);
return dispatch(
response,
type: types[2],
);
)
.catch(err => dispatch(
response,
type: types[2],
));
;
【问题讨论】:
console.log(res.json())
返回什么?
这是一个承诺。一个已解决的
您的调试器是否告诉您在 undefined
上调用了哪个 then
?
自从我使用 redux thunk 已经有一段时间了,我不确定,但我的猜测是 actionFoo 应该返回一个调度调用而不是直接调用 authCall 操作。也许这个例子(很久以前写的)可以帮助你:github.com/svenvandescheur/react-redux-consumerjs-example
@JoshuaR。当然,一个:this.props.doActionFoo(gameName, password).then() 我已经在上面的代码中注释了
【参考方案1】:
来自redux-thunk
Redux Thunk 中间件允许您编写返回的动作创建器 一个函数而不是一个动作
所以这意味着它不处理你的承诺。您必须添加redux-promise
以支持承诺
默认导出是一个中间件函数。如果它收到一个承诺, 它将发送 promise 的已解决值。它不会 如果 Promise 拒绝,则发送任何内容。
redux-thunk
与 redux-promise
之间的区别你可以阅读here
【讨论】:
您能否举例说明如何将其添加到我现有的代码中,或者我只需要将其添加到中间件中? @dazlious 只需将其添加到您的中间件 在添加 thunk 之前还是之后? 你有任何关于 connect 和 mapDispatchToProps 的工作示例吗?我无法正常工作 好的,那我做错了什么? :(这令人不安;)【参考方案2】:好的,几个小时后,我找到了解决方案。 redux-thunk 必须先于任何其他中间件。因为中间件是从右到左调用的,所以 redux-thunk return 在链中最后,因此返回 Promise。
import thunkMiddleware from 'redux-thunk';
const middlewares = [
thunkMiddleware,
// ANY OTHER MIDDLEWARE,
];
const store = createStore(
rootReducer(appReducer),
initialState,
compose(
applyMiddleware(...middlewares),
window['__REDUX_DEVTOOLS_EXTENSION__'] ? window['__REDUX_DEVTOOLS_EXTENSION__']() : f => f,
),
);
【讨论】:
以上是关于Redux-Thunk - 异步动作创建者承诺和链接不起作用的主要内容,如果未能解决你的问题,请参考以下文章
redux-thunk:错误:动作必须是普通对象。使用自定义中间件进行异步操作
在使用 Redux-Thunk 异步操作的 Promise 链中使用 setInterval
Redux-thunk 异步操作:使用自定义中间件进行异步操作