一篇让我们学习实践React的文章
时间:2023-03-12 16:07:58
科技观察
每天都在写业务代码,但是在写业务代码的时候,经常会觉得自己写的一些代码有点坑爹,但又不知道坑爹在哪里.在今天的文章中,我整理了项目中用到的一些小技巧点。状态逻辑复用在使用ReactHooks之前,我们一般都是复用组件,没有办法复用组件的内部状态。ReactHooks的引入很好的解决了状态逻辑复用,而在我们日常开发中可以实现什么样的状态逻辑复用呢?下面我列举几个我目前在项目中常用的状态复用。为什么useRequest要封装这个hook呢?加载数据时,有很多点可以提取到共享逻辑的加载状态。复用和异常处理constuseRequest=()=>{const[loading,setLoading]=useState(false);const[error,setError]=useState();construn=useCallback(async(...fns)=>{setLoading(true);try{awaitPromise.all(fns.map((fn)=>{if(typeoffn==='function'){returnfn();}returnfn;}));}catch(错误){setError(错误);}finally{setLoading(false);}},[]);return{loading,error,run};};functionApp(){const{loading,error,run}=useRequest();useEffect(()=>{run(newPromise((resolve)=>{setTimeout(()=>{resolve());},2000);}));},[]);return(
);}usePagination我们在使用表格的时候,一般都会使用分页。通过将分页封装成hooks,一是可以引入前端代码量,二是统一了前后端分页的参数,对后端也有帮助。对端口接口的约束。constusePagination=(initPage={total:0,current:1,pageSize:10,})=>{const[pagination,setPagination]=useState(initPage);//接口查询数据的请求参数constqueryPagination=useMemo(()=>({limit:pagination.pageSize,offset:pagination.current-1}),[pagination.current,pagination.pageSize]);consttablePagination=useMemo(()=>{return{...pagination,onChange:(页面,pageSize)=>{setPagination({...pagination,current:page,pageSize,});},};},[pagination]);constsetTotal=useCallback((total)=>{setPagination((prev)=>({...prev,total,}));},[]);constsetCurrent=useCallback((current)=>{setPagination((prev)=>({...prev,current,}));},[]);return{//对antd表使用分页:tablePagination,//对接口查询数据使用queryPagination,setTotal,setCurrent,};};除了上面例子中的两个钩子,其实定义钩子可以无处不在。只要有可以复用的公共逻辑,都可以定义为一个独立的钩子,然后在多个页面或组件中使用。我们在使用redux和react-router的时候,也会使用到它们提供的hooks。在合适的场景中给useState传入一个函数我们在使用useState的setState的时候,大部分时候都会给setState传入一个值,但实际上setState不仅可以传入普通数据,还可以传入一个函数。下面的极端代码描述了几个传入函数的例子。3秒后以下代码输出什么?如下代码所示,还有两个按钮,一个按钮点击后会延时三秒然后给count+1,第二个按钮点击后会直接给count+1,那么如果我先点击延时按钮,然后多次点击非延时按钮,三秒后count的值是多少?import{useState,useEffect}from'react';functionApp(){const[count,setCount]=useState(0);functionhandleClick(){setTimeout(()=>{setCount(count+1);},3000);}functionhandleClickSync(){setCount(count+1);}return(
count:{count}
延迟加一加一 );}exportdefaultApp;我们知道React的功能组件会在其内部状态或外部props发生变化时重新渲染。其实这个重新渲染就是重新执行这个功能组件。当我们点击延迟按钮时,因为三秒后count的值会发生变化,所以此时不??会重新渲染。然后点击直接加一按钮,计数值从1变为2,需要重新渲染。这里需要注意的是,虽然重新渲染了组件,但是在上一次渲染时调用了setTimeout,也就是说setTimeout中的count值是组件第一次渲染时的值。所以即使多次添加第二个按钮,三秒后,执行setTimeout回调时,引用的count值仍然初始化为0,所以三秒后count+1的值为1。如何延迟上面的代码三秒然后输出正确的值?这时候就需要使用setState的方法传入函数,代码如下:import{useState,useEffect}from'react';functionApp(){const[count,setCount]=useState(0);functionhandleClick(){setTimeout(()=>{setCount((prevCount)=>prevCount+1);},3000);}functionhandleClickSync(){setCount(count+1);}return(