使用react-router+hooks搭建基础框架
前言
最典型的一个react项目就是react-router+redux(可能再加上redux-thunk或saga),在hooks出来之后,redux也同步跟进加了很多hooks,但已经可以完全抛弃redux,仅仅使用useReducer等hooks来管理数据流了(大型、复杂项目的话,目前还是推荐redux)
这个版本的代码在这
步骤
前文中已经配置好webpack了,接下来让我们配置react-router以及reducer
react-router
先安装依赖:
npm i -S react-router-dom react-helmet
react-router-dom是基于react-router的库,里面加入了一些在浏览器运行环境下的功能,例如:Link、BrowserRouter、HashRouter。而其他的一些组件则是直接从react-router中导出的,例如:Switch、Route等等。
react-helmet用来动态改变title
路由及布局
路由及布局,就跟我们平时写的react应用是一样的,先写个最简单的就行,就不详细展开了,具体看代码即可,主要新增了3个文件:
- routes.js 定义路由
- layout 定义布局
- RouteWithSubRoutes react-router的嵌套路由组件
插曲
写了几个基础页面后,发现报这种错:
Module not found: Error: Can't resolve 'core-js/modules/es.array.slice'
看了一下package.json,果然,遗漏安装core-js了,因为@babel/preset-env依赖core-js,会跑到当前项目下去寻找core-js
因为用到的是core-js3,所以我们安装core-js3:
npm i core-js@3
redux
接下来就是全局状态管理,以往我们都是用redux及react-redux,不过在有了useReducer和useContext之后,已经可以替代了
在hooks之前createContext配合Context.Consumer也能读取全局状态,只不过很不方便,这篇文章讲的不错
简单来说,使用useReducer和useContext来接管redux,主要有3步,示例代码如下:
-
createContext创建一个全局context
js const Store = createContext(initState);
-
使用上一步的context,导出Provider组件,value中传入useReducer的state及dispatch
const [state, dispatch] = useReducer(reducer, initState);
return <Store.Provider value={{state, dispatch}}>
</Store.Provider>
接下来就是传统的写法了,dispatch(action()),显然每个页面都这么写的话,还是挺繁琐的
如果能像vue那样mapAction,直接调用action,那就方便多了
redux4中有一个bindActionCreators,跟mapAction作用类似传入action和dispatch,返回一个直接调用的action
而且代码多了之后,肯定是需要拆分reducer及action的,所以我们可以这样进行拆分:
- 建一个reducers文件夹
- 一个业务对应一个reducer文件,每个文件里定义actions、reducers
- 新增一个builder文件,遍历处理,将actions用dispatch包一层,reducers则简单合并,最后导出新的actions、一个新的root reducer
结构如下:
- redux
- reducers
- global.ts
- todo.ts
- index.ts
- builder.ts
- store.tsx
- 创建一个useRedux hooks,快捷使用state、dispatch
const {state, dispatch, actions} = useContext(Store);
更具体的代码就不一行行展示了,在tag-v2中可以详细查看
小结
可以看到,createContext+useContext+useReducer这3个react内置的api,已经足够应对小型项目的全局状态管理了