发布网友 发布时间:2024-10-02 09:15
共1个回答
热心网友 时间:2024-10-29 18:05
岁月悠悠,道路险阻,我们总是用顺其自然来敷衍人生道路上面的荆棘坎坷,却很少承认,真正的顺其自然是竭尽全部力量后的不强求,而并非是两手一摊,只有抱怨和埋怨的不作为。
前言使用过Vuex再来使用Rex我自己的感觉就是Rex的写法太复杂、太分散了,不像Vuex在一个文件里聚合所有东西。但现在Rex官方推出了RexToolkit,从此Rex写起来也能很爽了。
Rex是什么?Rex是一个使用叫做“action”的事件来管理和更新应用状态的模式和工具库?它以集中式Store的方式对整个应用中使用的状态进行集中管理,确保状态只能以可预测的方式更新。
RexToolkit是什么?RexToolkit是官方推荐的编写Rex逻辑的方法。它包含我们对于构建Rex应用程序必不可少的包和函数。RexToolkit的构建简化了大多数Rex任务,防止了常见错误,并使编写Rex应用程序变得更加容易。可以说RexToolkit就是目前Rex的最佳实践方式。
为了方便后面内容,之后RexToolkit简称RTK
从零开始搭一个RTK学习的最佳方法我个人觉得还是看官方文档比较权威:中文官方文档、英文官方文档。
在官方文档中其实提供了完整的RTK项目创建命令,但咱们学习就从基础的搭建开始吧。那么想手动搭建一个?RTK项目改如何做呢?
启动一个react项目这里直接创建一个react项目,然后我们再开始唠如何使用RTK
yarncreatereact-appmy-rex-toolkitcdmy-rex-toolkit安装RTK相关包和开发工具创建完项目以后我们开始安装RTK相关的东西
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex为了方便我们开发,这里推荐安装一下Rex的开发工具:rex-devtools,需要注意的是在chrome浏览器中我们也需要安装对应的插件:rex-devtools来结合使用。
//安装rex开发工具rex-devtoolsyarnaddrex-devtools-D基础开发流程安装完相关包以后开始编写基本的RTK程序
创建一个store文件夹
创建一个index.ts做为主入口
创建一个festures文件夹用来装所有的store
创建一个counterSlice.ts文件,并导出简单的加减方法
内容结构如下图:
相关代码如下:
//counterSlice.ts文件import{createSlice}from'@rexjs/toolkit';exportinterfaceCounterState{value:number;title:string}constinitialState:CounterState={value:0,title:"rextoolkitpre"};//创建一个SliceexportconstcounterSlice=createSlice({name:'counter',initialState,//定义recers并生成关联的操作recers:{//定义一个加的方法increment:(state)=>{state.value+=1;},//定义一个减的方法decrement:(state)=>{state.value-=1;},},});//导出加减的方法exportconst{increment,decrement}=counterSlice.actions;//默认导出exportdefaultcounterSlice.recer;//index.ts文件import{configureStore}from"@rexjs/toolkit";importcounterSlicefrom"./features/counterSlice.ts";//configureStore创建一个rex数据conststore=configureStore({//合并多个Slicerecer:{counter:counterSlice},});exportdefaultstore;基本代码开发完以后,我们需要看看应用到页面中是否OK,先把store加到全局,如下图:
对应的代码如下:
//index.ts文件importReactfrom'react';importReactDOMfrom'react-dom/client';import'./index.css';importAppfrom'./App';importreportWebVitalsfrom'./reportWebVitals';//rextoolkitimport{Provider}from'react-rex';importstorefrom'./store/index.ts';constroot=ReactDOM.createRoot(document.getElementById('root'));root.render(<React.StrictMode><Providerstore={store}><App/></Provider></React.StrictMode>);reportWebVitals();添加到全局以后我们如何使用呢?如下图:
相关代码如下:
//App.js文件//引入相关的hooksimport{useSelector,useDispatch}from'react-rex';//引入对应的方法import{increment,decrement}from'./store/features/counterSlice.ts';importlogofrom'./logo.svg';import'./App.css';functionApp(){//通过useSelector直接拿到store中定义的valueconst{value}=useSelector((store)=>store.counter)//通过useDispatch派发事件constdispatch=useDispatch()return(<divclassName="App"><headerclassName="App-header"><imgsrc={logo}className="App-logo"alt="logo"/>{/*页面中应用的代码*/}<p>{value}</p><buttononClick={()=>{dispatch(increment())}}>加</button><buttononClick={()=>{dispatch(decrement())}}>减</button></header></div>);}exportdefaultApp;到此就完成了RTK的使用,看一下效果:
如何传参?上面的项目中固定的加一减一,那如果我们想加多少就能动态加多少,那就需要传参。那如何传参呢?和rex的传参一样,如下图:
相关代码为:
//App.js文件import{useState}from'react';//引入相关的hooksimport{useSelector,useDispatch}from'react-rex';//引入对应的方法import{increment,decrement}from'./store/features/counterSlice.ts';importlogofrom'./logo.svg';import'./App.css';functionApp(){//通过useSelector直接拿到store中定义的valueconst{value}=useSelector((store)=>store.counter)//通过useDispatch派发事件constdispatch=useDispatch()//变量const[amount,setAmount]=useState(1);return(<divclassName="App"><headerclassName="App-header"><imgsrc={logo}className="App-logo"alt="logo"/>{/*页面中应用的代码*/}<p>{value}</p><inputvalue={amount}onChange={(e)=>setAmount(+e.target.value)}/><buttononClick={()=>{dispatch(increment({value:amount}))}}>加</button><buttononClick={()=>{dispatch(decrement())}}>减</button></header></div>);}exportdefaultApp;如何接收参数?接收参数的方式也和Rex一样,我们可以通过action来接收参数,如下图:
相关代码如下:
//counterSlice.ts文件import{createSlice}from'@rexjs/toolkit';exportinterfaceCounterState{value:number;title:string}constinitialState:CounterState={value:0,title:"rextoolkitpre"};//创建一个SliceexportconstcounterSlice=createSlice({name:'counter',initialState,//定义recers并生成关联的操作recers:{//定义一个加的方法increment:(state,{payload})=>{//action里面有type和payload两个属性,所有的传参都在payload里面state.value+=payload.value;},//定义一个减的方法decrement:(state)=>{state.value-=1;},},});//导出加减的方法exportconst{increment,decrement}=counterSlice.actions;//默认导出exportdefaultcounterSlice.recer;写完了那就效果如下:
如何实现一个异步请求?异步请求在我们的项目中时必不可少的,那如何实现一个异步请求呢?这里我“偷”了一个电影列表接口,咱们重新开一个slice,看一下多个模块的RTK是如何实现的。如下图:
相关代码为:
import{createSlice,createAsyncThunk}from'@rexjs/toolkit';exportinterfaceMovieState{list:object;totals:number}constinitialState:MovieState={list:[],totals:0};//请求电影列表constgetMovieListApi=()=>fetch('https://pcw-api.iqiyi.com/search/recommend/list?channel_id=1&data_type=1&mode=24&page_id=1&ret_num=48').then(res=>res.json())//thunk函数允许执行异步逻辑,通常用于发出异步请求。//createAsyncThunk创建一个异步action,方法触发的时候会有三种状态://pending(进行中)、fulfilled(成功)、rejected(失败)exportconstgetMovieData=createAsyncThunk('movie/getMovie',async()=>{constres=awaitgetMovieListApi();returnres;});//创建一个SliceexportconstmovieSlice=createSlice({name:'movie',initialState,recers:{//数据请求完触发loadDataEnd:(state,{payload})=>{state.list=payload;state.totals=payload.length;},},//extraRecers字段让slice处理在别处定义的actions,//包括由createAsyncThunk或其他slice生成的actions。extraRecers(builder){builder.addCase(getMovieData.pending,(state)=>{console.log("?~进行中!")}).addCase(getMovieData.fulfilled,(state,{payload})=>{console.log("?~fulfilled",payload);state.list=payload.data.liststate.totals=payload.data.list.length}).addCase(getMovieData.rejected,(state,err)=>{console.log("?~rejected",err)});},});//导出方法exportconst{loadDataEnd}=movieSlice.actions;//默认导出exportdefaultmovieSlice.recer;然后在主入口引入:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex0应用也是一样的,如下图:
相关代码为:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex1看一下具体的效果:
createAsyncThunkcreateAsyncThunk可以创建一个异步action,通常用于发出异步请求。方法触发的时候会有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)
extraRecersextraRecers可以让slice处理在别处定义的actions,包括由createAsyncThunk或其他slice生成的actions。刚才的代码里咱们处理的是createAsyncThunk,接下来看一下如何处理其他slice生成的actions。直接看一下counterSlice.ts中的increment方法如何处理吧,如下图:
相关代码为:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex2完事看一下具体的效果:
总结一下RTK的实现使我们对Rex的实现更加容易,说是目前最佳实践也不为过。整体总结一下:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex3直接创建一个RTK在我门熟悉如何使用RTK之后咱们再来看看官方提供一键生成的RTK应用。官方推荐的创建ReactRex新应用的方式有两种,都是基于?CreateReactApp,它利用了?RexToolkit?和Rex与React组件的集成.分别是:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex4个人觉得react和ts比较搭,这里就用Rex+TS模版来创建一个看看。还有个人比较喜欢yarn,所以这里用的是yarn的方式:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex5安装完成后可以看到基本我们需要的一些包就都有了,如下图:
看一下项目结构我们发现,相对于正常的react项目我们在src里面多了app和features两个文件夹。如下图:
点开文件夹可以看到里面的结构,app中其实就是两个入口文件,一个是hooks的,一个是store的。他们其实就是咱们自己搭建的RKT项目下的index.ts。如下图:
同样的点开features文件以后可以看到里面包了一个文件夹counter,这个其实可以理解成对不同的slice进行分组,目前官方的例子是一个计数器,所以分了一个counter文件夹。解析一下counter文件夹里面的代码:
counterSlice.ts计数器slice的核心代码,也就是RTK的实现
counterAPI.ts其实就是把异步请求单独提出来放在一起
Counter.tsx是计数器的视图文件,可以理解为html部分
Counter.mole.css是计数器的样式,也就是css部分
counterSlice.spec.ts对应生成的单元测试文件
具体结构如下图:
启动看一下:
//安装@rexjs/toolkit和react-rexyarnadd@rexjs/toolkitreact-rex6效果如下图:
到此整个RTK的使用就介绍完了,整体只属于一个基础讲解,如果项目中需要使用RTK的话,还需要仔细看一下官方文档。
若有帮助记得三连哦!???
原文:https://juejin.cn/post/7101688098781659172