redux教程,如何使用addMatcher添加自定义系统监听?
发布于 作者:苏南大叔 来源:程序如此灵动~redux
代码添加了action
之后,就可以定义extraReducers
。在内部的builder
可以提供addCase
方法/addMatcher
方法/addDefaultCase
方法。三种方法使用的场景是不同的,本文描述第二种方式addMatcher
。
大家好,这里是京城非著名互联网从业人员苏南大叔的技术博客,写写代码吹吹风的自留地。本文描述如何使用addMatcher
拦截redux
里面的action
。测试环境:win10
,node@16.14.2
,create-react-app@5.0.1
,reduxjs/toolkit@1.8.3
,react-redux@8.0.2
,chrome@103.0.5060.53
,redux-devtools-extension@3.0.11
。
定义钩子的标准
在前面的教程中,大家已经知晓了addCase
的使用方法,就是通过action.type
进行拦截的。那么,匹配的标准就是一个字不差的字符串匹配,可以匹配普通的type
字符串,也可以匹配三种状态变化的type
字符串。参考文章:
- https://newsn.net/say/redux-createasyncthunk.html
- https://newsn.net/say/redux-createasyncthunk-action.html
- https://newsn.net/say/redux-createasyncthunk-addcase.html
addMatcher
可以匹配的自由度更高,它可以根据state
和action
两个维度上进行匹配,支持自定义。实际上就是,在addMatcher
中,根据action
,可以使用任何想象到的条件去过滤。
.addMatcher(isAllOf(async_test2.fulfilled,isOk),(state,action)=>{
//...
})
上面这个例子中,要满足type
为async_test2.fulfilled
,同时要满足自定义判断标准isOk()
。
function isOk(action){
return action.payload.ok
}
这里可以使用的是否系列函数有:
测试用例
这里接着上一个例子,参考文章:
这个例子中,使用了isAllOf()
和isAnyOf()
,其实上就是and
和or
的变种写法。
多条addMatcher()
之间不冲突,和已有的addCase()
也不冲突,也就是说:添加addMatcher()
,可以获得多次匹配机会。
模拟的async_thunk
函数:
export const async_test1 = createAsyncThunk(
'sunan/async_test1',
async (id,{ requestId })=>{
return {id,requestId,ok:false};
}
);
export const async_test2 = createAsyncThunk(
'sunan/async_test2',
async (id,{ requestId })=>{
return {id,requestId,ok:true};
}
)
自定义的matcher
函数:
function isAllOf2(action){
let a2 = (action.type==='sunan/async_test2/fulfilled');
if(!a2) return false;
return isOk(action);
}
function isAnyOf2(action){
let a2 = (action.type==='sunan/async_test1/fulfilled');
if(a2) return true;
return (action.type==='sunan/async_test2/fulfilled');
}
function isOk(action){
return action.payload.ok
}
定义matcher
:
export const husband = createSlice({
name: 'husband',
initialState :{
unknown:[],
},
reducers: {
},
extraReducers: (builder) => {
builder
.addCase(async_test2.fulfilled,(state,action)=>{
console.log("addCase");
})
.addMatcher(isAllOf(async_test2.fulfilled,isOk),(state,action)=>{
console.log("addMatcher_isAllOf");
state.unknown.push(action.payload);
})
.addMatcher(isAllOf2,(state,action)=>{
console.log("addMatcher_isAllOf_alias");
state.unknown.push(action.payload);
})
.addMatcher(isAnyOf(async_test1.fulfilled,async_test2.fulfilled),(state,action)=>{
console.log("addMatcher_isAnyOf");
state.unknown.push(action.payload);
})
.addMatcher(isAnyOf2,(state,action)=>{
console.log("addMatcher_isAnyOf_alias");
state.unknown.push(action.payload);
});
},
});
addMatcher
定位位置
addCase()
/addMatcher()
/addDefaultCase()
这三个方法,定义是有先后顺序的。必须遵守这个顺序,才可以定义成功。否则可能会得到下面的类似错误提示信息:
Uncaught Error: `builder.addCase` should only be called before calling `builder.addMatcher`
相关文章
- https://redux.js.org/tutorials/essentials/part-5-async-logic#reducers-and-loading-actions
- https://newsn.net/say/redux-createasyncthunk.html
- https://newsn.net/say/redux-createasyncthunk-action.html
- https://newsn.net/say/redux-createasyncthunk-addcase.html
综述
再次声明一个观点,redux
并不是react
的附庸,两者不存在必然关系。虽然目前大多数时候,两者都是绑定在一起的。更多redux
的相关经验文章,请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。