我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

redux代码添加了action之后,就可以定义extraReducers。在内部的builder可以提供addCase方法/addMatcher方法/addDefaultCase方法。三种方法使用的场景是不同的,本文描述第二种方式addMatcher

苏南大叔:redux教程,如何使用addMatcher添加自定义系统监听? - redux-addmatcher
redux教程,如何使用addMatcher添加自定义系统监听?(图3-1)

大家好,这里是京城非著名互联网从业人员苏南大叔的技术博客,写写代码吹吹风的自留地。本文描述如何使用addMatcher拦截redux里面的action。测试环境:win10node@16.14.2create-react-app@5.0.1reduxjs/toolkit@1.8.3react-redux@8.0.2chrome@103.0.5060.53redux-devtools-extension@3.0.11

定义钩子的标准

在前面的教程中,大家已经知晓了addCase的使用方法,就是通过action.type进行拦截的。那么,匹配的标准就是一个字不差的字符串匹配,可以匹配普通的type字符串,也可以匹配三种状态变化的type字符串。参考文章:

addMatcher可以匹配的自由度更高,它可以根据stateaction两个维度上进行匹配,支持自定义。实际上就是,在addMatcher中,根据action,可以使用任何想象到的条件去过滤。

.addMatcher(isAllOf(async_test2.fulfilled,isOk),(state,action)=>{
    //...
})

上面这个例子中,要满足typeasync_test2.fulfilled,同时要满足自定义判断标准isOk()

function isOk(action){ 
  return action.payload.ok
}

这里可以使用的是否系列函数有:

测试用例

这里接着上一个例子,参考文章:

这个例子中,使用了isAllOf()isAnyOf(),其实上就是andor的变种写法。
多条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);
      });
  },
});

苏南大叔:redux教程,如何使用addMatcher添加自定义系统监听? - 可以触发多个监控
redux教程,如何使用addMatcher添加自定义系统监听?(图3-2)

addMatcher定位位置

addCase()/addMatcher()/addDefaultCase()这三个方法,定义是有先后顺序的。必须遵守这个顺序,才可以定义成功。否则可能会得到下面的类似错误提示信息:

Uncaught Error: `builder.addCase` should only be called before calling `builder.addMatcher`

苏南大叔:redux教程,如何使用addMatcher添加自定义系统监听? - addmatcher-error-addcase
redux教程,如何使用addMatcher添加自定义系统监听?(图3-3)

相关文章

综述

再次声明一个观点,redux并不是react的附庸,两者不存在必然关系。虽然目前大多数时候,两者都是绑定在一起的。更多redux的相关经验文章,请参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   redux