我正在使用redux-form和redux-api-middleware编写React / Redux应用程序,而我在将redux-form的onSubmit
函数与RSAA生命周期集成时遇到了问题。
redux-form文档说onSubmit
处理程序should return是一个承诺。在对承诺调用resolve
之前,表单的submitting
道具将为true
。
但是,在此应用中,我的API调用目前不使用promises(例如,通过fetch
)。我通过调度[CALL_API]
RSAA操作和reducing redux-api-middleware's response actions.
class MyReduxFormContainer extends Component {
render() {
return (
<MyReduxForm submit={this.props.submit} />
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
submit: function(values, dispatch) {
dispatch({
[CALL_API]: {
method: 'PATCH',
types: [
{
type: 'REQUEST',
endpoint: '...',
body: JSON.stringify(values)
},
'SUCCESS',
'FAILURE'
]
}
});
// Problem: redux-api-middleware-style API calls normally don't leverage promises.
// Out of the box, this library doesn't offer a promise to return.
}
}
};
export default connect(
// ...
mapDispatchToProps
)(MyReduxFormContainer)
我可以通过payload
RSAA回调传递承诺,然后可以在API响应后解析/拒绝承诺,但这似乎违反了“的规则动作创建者不应该引起副作用。“授予redux-api-middleware似乎会改变这个规则。
理论上我可以在fetch
处理程序中使用onSubmit
,而不是使用redux-api-middleware,但这不仅仅是让我的API的让步在整个应用程序中交互不一致,它也有可能重复我已经烘焙过的任何API中间件活动,例如设置默认标题,去降低/降低有效载荷等等。
有没有人有使用redux-form和redux-api-middleware的经验?
如果它只是redux-api-middleware,我希望在减少submitting
动作类型时通过改变表单的状态来简单地更改表单的ACTION_TYPE_[REQUEST|SUCCESS|FAILURE]
道具。但是从reducer直接修改表单的状态似乎是非标准的并且可能存在风险。 redux-form实现的示例似乎强调redux-form状态应该是透明的/只是间接操作。
任何想法/指示都将不胜感激!
终极版-API的中间件:
Redux的形式:
答案 0 :(得分:3)
最近我发现很优雅和通用的方式结合起来。 Here is article with explanation
export const formToApiAdapter = (dispatch, actionCreator, formatErrors) => (
(...args) => (
new Promise((resolve, reject) => (
dispatch(actionCreator(...args)).then(
(response) => {
if (response.error) {
return reject(formatErrors(response));
}
return resolve(response);
}
)
))
)
);
答案 1 :(得分:1)
由于缺乏更好的解决方案,我目前正在减少形式的dispatch({[CALL_API]})
处理程序中将我的submit
调用包含在Promise中。
class MyReduxFormContainer extends Component {
render() {
return (
<MyReduxForm submit={this.props.submit} />
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
submit: function(values, dispatch) {
// Solution: Wrap the [CALL_API] dispatch in a Promise
return new Promise((resolve, reject) => {
dispatch({
[CALL_API]: {
method: 'PATCH',
types: [
{
type: 'MY_PATCH_REQUEST'
endpoint: '...',
body: JSON.stringify(values)
},
{
type: 'MY_PATCH_SUCCESS',
payload: function (action, state, res) {
// Solution: resolve() the promise in the SUCCESS payload callback
// Changes `submitting` prop of MyReduxForm
resolve();
}
},
{
type: 'MY_PATCH_FAILURE',
payload: function (action, state, res) {
// Solution: reject() the promise in the FAILURE payload callback
// Changes `submitting` prop of MyReduxForm
reject();
}
}
]
}
});
});
}
}
};
export default connect(
// ...
mapDispatchToProps
)(MyReduxFormContainer)
最终,我对此代码架构非常不满意,此时我认为标准fetch
用法优于redux-api-middleware
。
API响应之后的触发效果足够标准作为一个问题,应该有比这种回调嵌套更优雅的解决方案,例如,使用承诺链。