基于TypeScript的Redux和React-Redux使用说明

目录

在类组件中使用redux

第二种写法,在类组件中使用react-redux改造

         第三种写法,在函数式组件中使用React-redux

         结合redux-thunk

         在redux中使用中间件

         redux-toolkit优化改造


在类组件中使用redux

1.首先安装:

npm install redux

2.创建reducer

3.在文件中创建store,将reducer传入createStore中:

4.类组件中通过getState()读取数据:

5.组件中通过定义action,派发action改变state中的数据:

 

6.接着回到reducer中,处理组件派发过来的action,并更新改变state中的数据:

7.最后一步,通过store.subscribe“发送订阅信息”,即实时更新组件中的数据:

但是以上代码需要改进,第5步中的action不应该直接放在组件中,而是应该将action定义在单独的文件中,方便后期的维护,同时借助TypeScript的类型检验来减少容易写错代码的风险,以及第6步中switch中的case参数不应该直接写字符串,应该也将其定义到单独的action文件中,供多个地方使用该action.type

改进:

在redux目录下创建一个language,将于language业务有关的目录全部迁移进去,并创建languageAction文件,在这统一定义相关的action

languageAction文件:

 在第6步中,将languageAction中定义的联合类型LanguageTypes传到函数的参数action中,从而享受TypeScript的类型检验

最后修改组件中第5步中的派发action方式,通过 languageAction.ts统一定义的actionCreator方法来定义action:

完成改进 

第二种写法,在类组件中使用react-redux改造

1.安装

npm install react-redux

如果要支持Typescript,还需安装:

npm install @types/react-redux --save-dev

在index.tsx中,用Provider将整个应用包裹起来

2.子组件中,引入相关:

3.在store.ts中定义所有state的类型:

4.回到子组件中,定义mapStateToProps和mapDispatchToProps

 

并将导出的组件包裹起来,把定义的mapStateToProps和mapDispatchToProps作为参数传入:

5.在组件中使用:

 

可以看出在类组件中使用React-redux十分繁琐,因此推荐第三种写法

第三种写法,在函数式组件中使用React-redux

1.在组件中获得全局store的数据,需要先引入useSelector:

但如果想要完美兼容Typescript,需要对useSelector进行以下封装:

 

其中rootState是在store.ts中定义的联合类型:

接着在组件中通过useSelector获取全局定义中的language和languageList两个数据

 

2.dispatch派发action

引入useDispatch:

 

 

  结合redux-thunk

    首先安装:

npm install redux-thunk

   为什么要redux-thunk?

   下面是homePage中的一段代码,我们把请求api的方法直接放在组件的componentDidMount中,

    但这时我们更希望将这段方法抽离成全局的方法,这样就不仅能服务于homePage这个页面,其它页面也可以使用,因此我们需要将这段方法与redux建立联系

再回来看redux的文件目录

除了定义文件hook.ts和store.ts,redux中的核心业务文件只有Action文件和Reducer文件,但ActionCreator只是提供定义action的方法,而Reducer文件中不允许有携带副作用的函数存在,因此目前来讲我们不能将请求api的方法放置在这里的任何一个文件中,这时就需要请求外援大名鼎鼎的redux-thunk了

在store.ts中引入redux-thunk和 applyMiddleware 

 

 在creatStore中使用:

 然后也要在action文件中定义相关的actionCreator:

引入:ThunkAction

 定义actionCreator

 注意ThunkFunction泛型中接收四个参数分别是

 1.函数的返回类型,这里没有返回,所以为void

2.state的类型

3.额外参数的类型,unKnow

4.action的类型,如果不加入RecommendProductAction类型,创建的giveMeDataActionCreator中将无法调用那三个dispatch(fetchRecommendProductxxxxxxxActionCreator( ))

 

最后,在homePage中使用,引入刚刚定义的giveMeDataActionCreator

 改造类组件中的mapDispatchToProps

改造componentDidmount

 

 在redux中使用中间件

为什么需要中间件?假设现在有一个需求,需要在每次dispatch actions时同时打印当前state,action以及更新后的state,这时,中间件允许我们在发送action时截取这个action,并且在这个过程中添加一些附加的操作,相当于对其进行了封装

  首先记住中间件格式

 在redux文件夹下创建文件夹middlewares

在actionLog.ts定义该中间件:

在store.ts中,将该actionLog中间件作为参数,传入到createStore的第二个参数,applyMiddleWare中

redux-toolkit优化改造

有没有发现每个actionCreator文件中都存在大量的冗余代码,模板代码。

比如:每个actionCreator中都需要定义action的type

 每个actionCreator中都需要定义action

每个reducer中都需要通过switch来写代码

 redux-toolkit就是用来解决这样的问题

安装:

npm install @reduxjs/toolkit

创建slice.ts

编写slice.ts

改造store.ts

将combineReducers改成从@reduxjs/toolkit中引入,而不再从redux中引入

 改为:

然后将ProductDetailSlice.reducer作为参数传入combineReducers中,记住一定是.reducer的形式

 

 在组件中使用:

引入productDetailSlice:

 通过productDetailSlice.actions.xxxx的方式来调用reducer

若需要在slice.ts文件中处理异步函数:

1.引入configureStore,

2.在store.ts中将原来的用createStore创建的store注释掉

 改成使用configureStore来创建store(这里的actionLog是之前创建的中间件)

 3.使用createAsyncThunk来创建异步函数

引入:

定义异步函数getProductDetail

4.将ProductDetailSlice中原来的 reducers改成extraReducers,并修改它们的名字

原来的ProductDetailSlice:

 修改后的ProductDetailSlice:


完成

使用redux-persist将redux存储持久化

redux-persist可以像localStorage或cookie的方式将redux中的数据存储起来

安装

npm install redux-peisist

在store.ts中引入persistStore,persistReducer和storage

 定义配置选项persistConfig

第二个参数storage实际上就是localStorage,而whiteList是白名单,代表只存储白名单里的数据,这里只存储user这个reducer

同时,也有黑名单blackList,与whiteList相反,除了列表中的reducer,其它所有的reducer都将会被储存

 然后用引入的persistReducer来定义新的persistedReducer,将刚刚定义的配置选项persistConfig和rootReducer作为参数传入 :

然后,将

configureStore中的reducer替换成刚刚定义的新persistedReducer

 将

改成

使用一开始引入的persistStore,将新的store作为参数传入,得到persistor

最后修改导出的store

原来的导出方式:

改成:

persistor一同导出

 如何使用:

在index,ts中导入上边导出的store和persistor联合体

 以及引入PersistGate

 然后将rootStore.store作为全局参数传入Provider的store中

将刚刚引入的PersistGate将<App />包裹起来,并将rootStore中的persistor作为参数传入.

注意,PersistGate除了接收persistor参数,还可以接收一个"loading",可用来定义加载持久化store时的加载界面,若写成<PersistGate loading={ null }></PersistGate>,则在加载时界面直接显示空白

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值