[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwgkhxVfMdDIqL2Y8VVz54MiMep3RYLYHXYetY_lKZHA":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":12,"notice":12,"visitCount":28,"commentCount":29,"keywords":30},174,"2025-12-06T10:29:46.456Z","react-redux的现代化用法 - 拥抱@reduxjs/toolkit","首先我们来介绍一下这篇文章的主角：`@reduxjs/toolkit`，一个全新的react redux集合。\n@reduxjs/toolkit诞生的原因，在官网（[https://redux-toolkit.js.org/introduction/getting-started](https://redux-toolkit.js.org/introduction/getting-started)）上给出了明确的说法：\n> \"Configuring a Redux store is too complicated\"\n\"I have to add a lot of packages to get Redux to do anything useful\"\n\"Redux requires too much boilerplate code\"\n\n简单的说，就是原来的react redux写法太复杂，并且需要添加更多的npm包去实现redux的逻辑，而且老版本中有一堆的模版代码写法。\n\n那么新的`@reduxjs/toolkit`和旧的比，有哪些新颖写法，这篇文章对通用的几个写法做了一些对比。\n\n## 对比\n- 老写法\n需要依赖：\n```package.json\n...\n\"redux-logger\": \"^3.0.6\",\n\"redux-thunk\": \"^2.3.0\",\n\"redux\": \"^4.0.0\",\n\"react-redux\": \"^7.2.0\",\n...\n```\n1. store创建\n```store.ts\nimport { legacy_createStore as createStore, applyMiddleware, compose } from 'redux'\nimport thunkMiddleware from 'redux-thunk'\nimport logger from 'redux-logger'\nimport rootReducer from '../reducers'\n\nconst composeEnhancers = typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__\n  ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({\n    // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...\n  })\n  : compose\n\nconst middlewares = [\n  thunkMiddleware\n]\n\nif (process.env.NODE_ENV === 'development') {\n  middlewares.push(logger)\n}\n\nconst enhancer = composeEnhancers(\n  applyMiddleware(...middlewares),\n  // other store enhancers if any\n)\n\nexport default function configStore () {\n  const store = createStore(rootReducer, enhancer)\n  return store\n}\n```\n\n2. reducer集合\n```rootReducer.ts\nimport { combineReducers } from 'redux'\nimport counter from './counter'\n\nexport default combineReducers({\n  counter\n})\n```\n3. 声明方法case\n```constants/counter.ts\nexport const ADD = 'ADD'\nexport const MINUS = 'MINUS'\n```\n\n4. 声明action方法\n```actions/counter.ts\nimport {\n  ADD,\n  MINUS\n} from '../constants/counter'\n\nexport const add = () => {\n  return {\n    type: ADD\n  }\n}\nexport const minus = () => {\n  return {\n    type: MINUS\n  }\n}\n\n// 异步的action\nexport function asyncAdd () {\n  return dispatch => {\n    setTimeout(() => {\n      dispatch(add())\n    }, 2000)\n  }\n}\n```\n\n5. 具体的某一个reducer\n```counter.ts\nimport { ADD, MINUS } from \"../constants/counter\";\n\nconst INITIAL_STATE = {\n  num: 0,\n};\n\nexport default function counter(state = INITIAL_STATE, action) {\n  switch (action.type) {\n    case ADD:\n      return {\n        ...state,\n        num: state.num + 1,\n      };\n    case MINUS:\n      return {\n        ...state,\n        num: state.num - 1,\n      };\n    default:\n      return state;\n  }\n}\n\n```\n6. 调用reducer\n```index.tsx\n...\n// 第一种，component组件，如果你要将reducer绑定为组件的属性使用，那么要使用connect函数\nexport default connect(({ counter }) => ({\n  counter\n}), (dispatch) => ({\n  add () {\n    dispatch(add())\n  },\n  dec () {\n    dispatch(minus())\n  },\n  asyncAdd () {\n    dispatch(asyncAdd())\n  }\n}), IndexComponent) // IndexComponent是你的组件\n// 然后通过this.props去读取属性或者调用方法\n\n// 第二种，如果你要使用函数式组件，那么可以使用useSelector和useDispatch去使用\nconst dispatch = useDispatch();\ndispatch(add())\n...\n```\n\n从上面老的写法中，我们可以看出，在声明、使用redux的过程中，存在着很多繁琐的步骤。比如你需要创建一个新的reducer，那么上面counter的写法，你都得来一遍，每一个步骤又臭又长，把一个读写的逻辑搞的太过于复杂，模版代码就如counter的reducer文件中一样。\n\n- 新写法\n需要依赖:\n```package.json\n...\n\"@reduxjs/toolkit\": \"^2.8.2\",\n...\n```\n光这一个库，就包含了很多快捷写法：\n- [x] configureStore()\n- [x] createReducer()\n- [x] createAction()\n- [x] createSlice()\n- [x] combineSlices()\n- [x] createAsyncThunk\n...\n我这里只罗列了基本使用方法。从这个列表中的函数名就可以看出，`@reduxjs/toolkit`的模块化更清晰明确。\n\n下面我们看看如何使用。\n1. 创建store\n```store.ts\nimport { configureStore } from \"@reduxjs/toolkit\";\nimport counter from \"./modules/counter\";\n\nexport default configureStore({\n  reducer: {\n    counter: counter,\n  },\n});\n```\n2. 创建一个reducer，就是上面的counter\n```counter.ts\nimport { createSlice } from \"@reduxjs/toolkit\";\n\nconst counterReducer = createSlice({\n  name: \"Counter\",\n  initialState: {\n    num: 0\n  },\n  reducers: {\n    add: (state, action) => {\n      state.num = state.num + 1;\n    },\n    minus: (state, action) => {\n      state.num = state.num - 1;\n    },\n    asyncAdd: (state, action) => {\n      setTimeout(() => {\n        state.num = state.num + 1;\n      }, 2000)\n    },\n  },\n});\n\nexport const { add, minus, asyncAdd } = userReducer.actions;\n\nexport default counterReducer.reducer;\n```\n\n3. 函数组件使用（不要再用component组件了）\n```index.tsx\nimport {\n  add,\n} from \"@/store/modules/counter\";\n...\nconst num = useSelector((state: any) => state.counter.num);\nconst dispatch = useDispatch();\nconst handleAddAction = () => dispatch(add())\n...\n```\n到此结束。\n\n通过上面的新老写法对比，新写法的简单几步就可以将以前复杂的action、state简化到一个文件中，并且功能清晰，我也相信你已经对`@reduxjs/toolkit`有了进一步了解，所以尽可能使用新的写法去简化我们的代码吧。\n\n\n","这篇文章介绍一下react redux的现代化写法，完全一改之前繁琐的模版写法。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",32,{"id":24,"name":26,"parentId":21},"前端",[],34,0,"react-redux,react redux, reduxjs/toolkit, redux, redux-thunk,react"]