如何在多个动作创作者传递到单个listener中间件在Redux工具箱?



我想将state保存到我的数据库中,无论何时它的任何属性发生变化。我目前有两个中间件将dispatch我的saveTrip功能。

这两个中间件是相同的,但是监听不同的actioncreator。

Store.js:

listenerMiddleWare.startListening({
actionCreator: setOrigin,
effect: async(action, listenerAPI) => {
listenerAPI.cancelActiveListeners();
// await listenerAPI.delay(1000)
console.log("side effect origin");
listenerAPI.dispatch(saveTrip(action.payload))
}
})
listenerMiddleWare.startListening({
actionCreator: setDestination,
effect: async(action, listenerAPI) => {
listenerAPI.cancelActiveListeners();
// await listenerAPI.delay(1000)
console.log("side effect destination");
listenerAPI.dispatch(saveTrip(action.payload))
}
})

Savetrip功能:

export const saveTrip = createAsyncThunk(
'trip/saveTrip',
debounce(async (payload, thunkAPI) => {
const trip = thunkAPI.getState().trip
try {
fetch(
'http://localhost:5000/savetrip', {
mode: 'cors',
credentials: 'include',
method: "post",
body: JSON.stringify({trip}),
headers: {
'Content-Type': 'application/json'
},
})
.then(res => res.json())
.then(response => {
console.log(response)
thunkAPI.dispatch(setMongoID(response))
})
} catch (error) {
console.log(error);
}
}, 2000)
)

我甚至没有使用当我调用saveTrip时传递的有效载荷,因为我保存了state条目。我没有任何错误,但是如果我需要更多的侦听器,我的代码就显得多余了。有更好的方法吗?我基本上是想在状态改变时将我的状态保存到DB中。

你可以使用匹配器

listenerMiddleWare.startListening({
matcher: isAnyOf(setOrigin, setDestination),
effect: async(action, listenerAPI) => {
listenerAPI.cancelActiveListeners();
// await listenerAPI.delay(1000)
console.log("side effect origin");
listenerAPI.dispatch(saveTrip(action.payload))
}
})
也就是说,你使用createAsyncThunk非常错误你的思考在请求被发送到服务器之前就已经完成了,远在响应到达之前。最后你不需要dispatch,只需要return。坦克自动调度一个.fulfilled动作。

而且,这种脱开会导致非常奇怪的效果。你需要在另一个层次上做这件事,最好是在你的dispatch之外。

export const saveTrip = createAsyncThunk(
'trip/saveTrip',
async (payload, thunkAPI) => {
const trip = thunkAPI.getState().trip
try {
const result = await fetch(
'http://localhost:5000/savetrip', {
mode: 'cors',
credentials: 'include',
method: "post",
body: JSON.stringify({trip}),
headers: {
'Content-Type': 'application/json'
},
})
const response = await result.json()
return response
} catch (error) {
console.log(error);
}
}
)
// then use `saveTrip.fulfilled` in your matcher.

最新更新