我正试图绕过Redux actionCreators中的状态;而是执行以下操作(在reducer中执行ajax操作)。为什么我需要为此访问状态 - 因为我想使用存储在状态中的CSRF令牌执行ajax。
有人可以告诉我以下是否被认为是不良做法/反模式?
export const reducer = (state = {} , action = {}) => {
case DELETE_COMMENT: {
// back-end ops
const formData = new FormData();
formData.append('csrf' , state.csrfToken);
fetch('/delete-comment/' + action.commentId , {
credentials:'include' ,
headers:new Headers({
'X-Requested-With':'XMLHttpRequest'
}) ,
method:'POST' ,
body:formData
})
// return new state
return {
...state ,
comments:state.comments.filter(comment => comment.id !== action.commentId)
};
}
default: {
return state;
}
}
答案 0 :(得分:7)
来自redux文档:
改变状态的唯一方法是发出一个动作,一个描述发生的事情的对象。 不要将API调用放入reducers。 Reducers只是纯函数,它采用先前的状态和动作,并返回下一个状态。记住要返回新的状态对象,而不是改变以前的状态。
行动应描述变化。因此,该操作应包含新版本状态的数据,或者至少指定需要进行的转换。因此,API调用应该进入异步操作,以分派操作来更新状态。减速器必须始终是纯净的,没有副作用。
查看async actions了解详情。
redux示例中的异步操作示例:
function fetchPosts(subreddit) {
return (dispatch, getState) => {
// contains the current state object
const state = getState();
// get token
const token = state.some.token;
dispatch(requestPosts(subreddit));
// Perform the API request
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then(response => response.json())
// Then dispatch the resulting json/data to the reducer
.then(json => dispatch(receivePosts(subreddit, json)))
}
}
答案 1 :(得分:4)
根据redux指南。
减速机保持纯净非常重要。你应该在减速机内做的事情:
如果你问它是否是反模式,那么它是绝对的。
但是如果你问什么是解决方案。
例如在你的动作创作者(仅举例)中
export function deleteCommment(commentId) {
return dispatch => {
return Api.deleteComment(commentId)
.then( res => {
dispatch(updateCommentList(res));
});
};
}
export function updateCommentList(commentList) {
return {
type : UPDATE_COMMENT_LIST,
commentList
};
}
编辑:您可以访问状态 -
export function deleteCommment(commentId) {
return (dispatch, getState) => {
const state = getState();
// use some data from state
return Api.deleteComment(commentId)
.then( res => {
dispatch(updateCommentList(res));
});
};
}