我是来自Redux Thunk的Redux Saga的新手。在某些情况下,我需要知道API调用是否失败,或者是否从我调用该操作的视图内部成功。使用Redux Thunk,我会做类似以下的事情。
我的组件和动作创建者看起来像这样:
class MyComponent extends Component {
componentDidMount() {
this.props.actions.fetchItems()
.then(result => {
if (result.status === 'OK') {
console.log('Request succeeded, take particular action in this view')
}
else {
console.log('Request failed, take other action in this view')
}
})
}
render() {
return (
<div>My view</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
return {
items: state.items,
}
}
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({
...actions,
}, dispatch),
}
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(MyComponent)
import * as t from './actionTypes'
import {CALL_API} from '../api'
const xhrGetItems = (params) => (dispatch, getState) => {
const action = {
[CALL_API]: {
type: t.XHR_ITEMS_FETCH,
endpoint: `http://www.example.com/myendpoint`,
method: 'get',
}
}
return dispatch(action)
}
我的API中间件捕获具有CALL_API
属性的所有操作,使用ajax库进行适当的调用,然后返回已履行的承诺。我的reducer设置为处理api调用的每个可能状态(成功,失败,挂起)。一直以来,我仍然可以在我的视图中检查调用的结果。
所以我的问题是,如何通过Redux Saga实现这一目标?现在我的saga api中间件正在做它应该做的一切,但是当我在视图中调用fetchItems()
时,结果是一个普通的JS对象,所以我无法检查它是否成功。
我也可能完全错误地解决这个问题。任何建议都非常感谢。
答案 0 :(得分:2)
使用redux和redux-saga的常见模式是为API调用创建3个Actions。在你的情况下,我会创建:
你的传奇看起来像这样:
GCC
传奇已经干净地抽象出API副作用。减速机可以专注于国家管理:
function* watchListItemsStart() {
yield takeLatest(LIST_ITEMS_START, listItemsStartFlow)
}
function* listItemsStartFlow() {
try {
const result = yield call(api.getItems)
if (result.status === 'OK') {
yield put(LIST_ITEMS_SUCCEEDED, items)
} else {
throw new Error(result.error)
}
} catch (error) {
yield put(LIST_ITEMS_FAILED, error)
}
}
现在,您可以在商店中获得所需的一切,可以在组件中进行选择和反应。
switch (action.type) {
case LIST_ITEMS_START:
return {
...state,
isLoading: true,
error: null,
items: [],
}
case LIST_ITEMS_SUCCEEDED:
return {
...state,
isLoading: false,
items: action.payload.items,
}
case LIST_ITEMS_FAILED:
return {
...state,
isLoading: false,
error: action.payload.error.getMessage(),
}
}
这里重要的一点是,你的组件变得非常愚蠢。它只是获取道具并且不处理API调用的结果(此处没有class MyComponent extends Component {
componentDidMount() {
this.props.fetchItems()
}
render() {
const { isLoading, items, error } = this.props
// Here you can react to the different states.
return (
<div>My view</div>
)
}
}
connect(state => ({
isLoading: itemsSelectors.isLoading(state),
items: itemsSelectors.getItems(state),
error: itemsSelectors.getError(state),
}), {
fetchItems: actions.fetchItems
})(MyComponent)
)。
我希望这个答案可以帮到你。