You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Redux中switch分支与default抛出错误的拦截行为差异

Redux Reducer与中间件错误处理的差异解析

咱们先把你的代码摆出来,再一步步拆解问题:

初始版本的Reducer与中间件

const reducer = ( state = { username : '', token : '?' }, action ) => { 
  switch (action.type){ 
    case 'SET_TOKEN': 
      state = { ...state, token : action.payload } 
      break 
    case 'SET_USERNAME': 
      state = { ...state, username : action.payload } 
      break 
    case 'SET_USERNME': 
      throw new Error("Errore, nessuna azione corrispondente") 
      break 
  } 
  return state 
} 

const logger = (store) => (next) =>(action) => { 
  console.log(store, next, action); 
  next(action); 
} 

const error = (store) => (next) =>(action) => { 
  try{ 
    console.log("Checking errors"); 
    next(action); 
  }catch(e){ 
    console.log("Error is: " +e); 
  } 
} 

const middleware = applyMiddleware(logger, error); 

当你派发SET_USERNME这个action时,控制台会打印错误但应用还能正常跑,核心原因在于中间件的执行顺序和错误捕获逻辑:

  • Redux中间件是按applyMiddleware里的顺序从左到右执行的:先跑logger,再跑error,最后才到reducer。
  • 当logger调用next(action),会把action传给error中间件;error里的next(action)会把action传给reducer。
  • reducer匹配到SET_USERNME分支后抛出错误,这个错误会立刻被error中间件的try/catch捕获,控制台打印错误信息,但错误不会向上冒泡到应用的其他部分,Redux会保持原有状态,所以应用不会崩溃。

修改后的Reducer版本

switch (action.type){ 
  case 'SET_TOKEN': 
    state = { ...state, token : action.payload } 
    break 
  case 'SET_USERNAME': 
    state = { ...state, username : action.payload } 
    break 
  default: 
    throw new Error("Errore, nessuna azione corrispondente") 
    break 
} 

现在来说两种写法的核心差异:

1. 错误触发的范围不同

  • 第一种写法:只有当action.type严格等于SET_USERNME时才会抛错,其他未匹配的action(比如随便写一个SET_XXX)会跳出switch,执行最后的return state,返回原状态,不会触发任何错误。
  • 第二种写法:所有未匹配到SET_TOKEN/SET_USERNAME的action都会触发错误,不管是SET_USERNME还是其他任意未定义的action类型,都会进入default分支抛错,覆盖的范围要大得多。

2. Reducer的返回逻辑差异

  • 第一种写法:当触发SET_USERNME抛错时,reducer函数会立刻终止,不会执行最后的return state;但因为错误被中间件捕获,Redux不会使用这个未完成的执行结果,而是维持之前的状态。
  • 第二种写法:触发default分支抛错时,同样会终止reducer的执行,没有返回值,但错误同样被error中间件捕获,Redux依旧保持原有状态,应用也不会崩溃。

本质上两种情况应用都能正常运行的原因是一样的:你的error中间件刚好在reducer之前执行,把reducer抛出的所有异常都拦截并处理了,阻止了错误影响到应用的其他逻辑。

内容的提问来源于stack exchange,提问作者DxW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:00:50