我正在将一些现有的 redux 代码转换为工具包方式。我们有很多触发 thunk 的动作(从后端加载数据)但没有减速器。我们的模式是加载/成功/失败三元组。基本上只有成功和失败需要reducer语句。我如何使用工具包做到这一点?我是否必须放入一个只为加载操作返回未更改状态的减速器?
1 回答
1
使用 redux-toolkit 你有几个选项在这里......
1. 现有的 thunk + RTK 动作
如果您只需要使用加载的数据更新商店的一个切片,您可以reducers
在该切片的属性中创建“成功”和“失败”操作。然后,更改您的 thunk 以调度那些而不是旧的成功/失败操作。
const slice = createSlice({
name: 'data',
initialState: {},
reducers: {
fetchDataSuccess(state, action) {
// Do something with the response
},
fetchDataError(state, action) {
// Do something with the error
}
}
}
const { fetchDataSuccess, fetchDataError } = slice.actions
export function fetchData() {
return dispatch => api.getData()
.then(response => dispatch(fetchDataSuccess(response.data)))
.catch(error => dispatch(fetchDataError(error))
}
export default slice.reducer
2.现有的thunk +extraReducers
如果您不想重构现有的 thunk,或者如果操作将跨多个切片使用,则可以使用该extraReducers
属性。
// These can also be defined in a separate file and imported
const FETCH_SUCCESS = 'data/FETCH_SUCCESS'
const FETCH_FAIL = 'data/FETCH_FAIL'
export function fetchData() {
return dispatch => api.getData()
.then(response => dispatch({ type: FETCH_SUCCESS, payload: response.data }))
.catch(error => dispatch({ type: FETCH_FAIL, payload: error }))
}
const slice = createSlice({
// ... the usual properties
extraReducers: {
[FETCH_SUCCESS](state, action) {
// Do something with the response
},
[FETCH_FAIL](state, action) {
// Do something with the error
}
}
}
3.createAsyncThunk
这种方法与上述方法类似,但该createAsyncThunk
实用程序会为您处理很多事情,例如捕获错误、在正确的时间调度操作等。
const fetchData = createAsyncThunk(
'data/fetchData',
() => api.getData().then(response => response.data)
)
const slice = createSlice({
// ... the usual properties
extraReducers: {
[fetchData.fulfilled](state, action) {
// Do something with the response
},
[fetchData.rejected](state, action) {
// Do something with action.error
}
}
}
// Components still call this like a normal function: fetchData()
export { fetchData }
export default slice.reducer
无论您最终采用哪种方式,如果您不使用“加载”操作(或.pending
from createAsyncThunk
),则无需将其添加到reducers
orextraReducers
中。
于 2020-07-01T16:03:41.940 回答