当前位置: 首页 > 科技观察

使用React-query解决你一半的状态管理问题

时间:2023-03-14 08:52:45 科技观察

根据资料,前端需要管理的“状态”有两种:用户交互的中间状态服务器状态在老项目中,Redux而Mobx通常使用“全局状态管理方案”来无差别地对待它们。其实它们有很大的不同:组件的isLoading、isOpen等用户交互的中间状态,这种“状态”的特点是:以“同步”的形式更新“状态”完全由前端“状态”相对独立(不同的组件有自己的isLoading)这种“状态”通常保存在组件内部。当“状态”需要跨组件层次结构传递时,通常会使用ContextAPI。Redux之类的“全局状态管理解决方案”将用于大规模“状态”。服务器状态当我们从服务器请求数据时:data);},[])//处理数据}返回的数据通常作为“状态”存储在组件内部(如App组件的数据状态)。如果是需要复用的通用“状态”,通常会保存在Redux等“全局状态管理方案”中。这样做有两个缺点:1、需要反复处理请求的中间状态。为了让App组件健壮,我们还需要处理请求和错误的中间状态:functionApp(){const[data,updateData]=useState(null);const[isError,setError]=useState(false);const[isLoading,setLoading]=useState(false);useEffect(async()=>{setError(false);setLoading(true);try{constdata=awaitaxios.get('/api/user');updateData(数据);}catch(e){setError(true);}setLoading(false);},[])//处理数据}这种一般的中间状态处理逻辑可能会在不同的组件中重复多次。2、“缓存”的本质不同于“状态”,不同于交互的中间状态。服务器状态应归类为“缓存”。它具有以下特性:通常以“异步”的形式请求和更新“状态”受请求的数据源控制,不受前端控制。“状态”可以被不同的组件共享,作为一个“缓存”可以被不同的组件共享。更多的问题需要考虑,比如:缓存失效缓存更新Redux当然方便。然而,以不同的方式对待不同类型的“状态”可以使项目更易于管理。这里推荐使用React-Query来管理服务器状态。另一种选择是SWR[1]。从这里可以看出它们的区别[2]认识React-QueryReact-Query是一个基于hooks的数据请求库。我们可以用React-Query重写前面的例子:import{useQuery}from'react-query'functionApp(){const{data,isLoading,isError}=useQuery('userData',()=>axios.get('/api/user'));if(isLoading){return

loading
;}return(
    {data.map(user=>>{user.name})}
)}React-Query中的Query是指一个异步请求的数据源。在示例中,userData字符串是此查询的唯一键。可以看到,React-Query封装了完整的请求中间状态(isLoading、isError...)。不仅如此,React-Query还为我们做了以下工作:当多个组件请求同一个查询时,只发送一个请求。缓存数据失效/更新策略(判断缓存是否适合失效,失效后自动请求数据)清理无效数据垃圾CRUD处理有2个钩子:useQuery处理数据查询useMutation处理数据增/删/改在下面例如,点击“创建用户”按钮将发起创建用户的post请求:import{useQuery,queryCache}from'react-query';unctionApp(){const{data,isLoading,isError}=useQuery('userData',()=>axios.get('/api/user'));//新用户const{mutate}=useMutation(data=>axios.post('/api/user',data));return(
    {data.map(user={user.name})}{mutate({name:'kasong',age:99})}}>Createuser
)但是userData查询对应的数据不会被点击Update,因为还没有过期。所以我们需要告诉React-Query,userData查询对应的缓存已经过期,需要更新:import{useQuery,queryCache}from'react-query';functionApp(){//...const{mutate}=useMutation(userData=>axios.post('/api/user',userData),{onSuccess:()=>{queryCache.invalidateQueries('userData')}})//...}通过调用mutate方法,该请求将被触发。当请求成功时,会触发onSuccess回调,回调中会调用queryCache.invalidateQueries,并将userData对应的querycache设置为invalidate。这样React-Query会重新请求userData中query对应的数据。总结通过使用像React-Query(或SWR)这样的数据请求库,您可以将服务器端状态从全局状态中解放出来。这给我们带来了很多好处:使用公共钩子来处理请求和中间状态冗余请求合并缓存的更新/失效策略Redux和其他“全局状态管理解决方案”可以更专注于“前端中间状态”处理参考资料[1]SWR:https://swr.vercel.app/[2]这里:https://react-query.tanstack.com/comparison【小编推荐】为什么你学不会Python,入门的4个陷阱用Python累了默认系统字体?这就是在Windows10上做出改变的方法。5G手机要大卖之前,首先要解决这些问题。教你用Python抓取百度搜索结果并保存。揭秘2021年春晚舞台上出现的黑科技——XR技术