原文:sourl.cn/F95CrZ,代码仓库地址:https://github.com/dabit3/react-state-5-ways在React中,好像数不胜数一种处理状态管理的方法。了解各种库,如何在它们之间进行选择以及它们的工作方式是一件令人头疼的事情。当我学习新东西时,我喜欢比较实现相同功能的库。这有助于我理解各种库之间的差异,并形成我在构建应用程序时如何选择使用它们的心智模型。在本文中,我将介绍如何在ReactApp中使用5个最流行的库/API(使用最现代和最新版本的库)如何在ReactApp程序中使用全局状态管理,并达到相同的效果。Recoil[1]MobX[2]XState[3]Redux(withhooks)[4]Context[5]我也会尝试解释它们之间的区别,本文以概述-代码-结论的方式进行解释。为了演示APIS,我们将使用这些库来创建一个创建和显示笔记的应用程序。开始如果你准备好了,那么请创建一个新的ReactApp,我们将用它来开始我们的实践:npxcreate-react-appreact-state-examplescdreact-state-examples无论何时何地,使用start命令开始你的订单。npmstartRecoilRecoilDocs[6]代码行:30关于Recoil,我最喜欢的是它基于Hooks的API以及它的直观性。与其他一些库相比,我认为Recoil的API比大多数库都简单。Recoil实践在开始使用Recoil之前,首先安装依赖项:npminstallrecoil接下来,将RecoilRoot添加到App程序的根/入口点:importAppfrom'./App'import{RecoilRoot}from'recoil'exportdefaultfunctionMain(){return();}接下来,要创建一些状态,我们将使用Recoil中的一个原子并设置一个键和一些初始状态:import{atom}from'recoil'constnotesState=atom({key:'notesState',//uniqueID(withrespecttootheratoms/selectors)default:[],//defaultvalue(akainitialstate)});现在,您可以在应用程序的任何位置使用Recoil中的useRecoilState。这是一个使用Recoil实现的笔记App:importReact,{useState}from'react';import{RecoilRoot,atom,useRecoilState}from'recoil';constnotesState=atom({key:'notesState',//uniqueID(withrespecttootheratoms/selectors)default:[],//defaultvalue(akainitialstate)});exportdefaultfunctionMain(){return();}functionApp(){const[notes,setNotes]=useRecoilState(notesState);const[input,setInput]=useState('')functioncreateNote(){constnotesArray=[...notes,input]setNotes(notesArray)setInput('')}return(
Mynotesapp
CreateNotesetInput(e.target.value)}/>{notes.map(note=>注意:{note})});}文档选择器中的反冲选择器用于计算基于状态的派生属性。这使我们能够避免冗余状态,通常无需使用reducer来保持状态同步和有效。相反,最小状态集存储在原子中。使用Recoil选择器,您可以根据状态计算派生属性,例如,可能是过滤后的待办事项数组(在待办事项应用程序中)或已发货订单数组(在电子商务应用程序中):import{selector,useRecoilValue}from'recoil'constcompletedTodosState=selector({key:'todosState',get:({get})=>{consttodos=get(todosState)returntodos.filter(todo=>todo.completed)}})constcompletedTodos=useRecoilValue(completedTodosState)结论Recoil文档说:“Recoil是React状态管理的实验性使用工具集。”当我决定在生产中使用该库时,听到“实验性”可能会非常令人担忧,所以至少现在,我不确定我现在对使用Recoil感觉如何。Recoil很棒,我会在我的下一个应用程序中使用它,但担心实验性能,所以我会密切关注它,但现在不要在生产中使用它。MobxMobXReactLiteDocs[7]代码行:30自从我在Redux之后使用了MobXReact,它一直是我最喜欢的用于管理React状态的库之一。多年来,两者之间存在明显差异,但对我而言,我不会改变我的选择。MobXReact现在有了轻量级版本(MobXReactLite),专门为函数式组件而生,速度更快,体积更小。MobX有observables和观察者的概念,但是observableAPI已经改变,你可以使用makeAutoObservable来为你处理一切,而不是指定你想要观察的每一个项目。如果你希望数据是反应式的并且需要修改存储,你可以用观察者包装组件。MobX实践在开始使用Mobx之前,首先安装依赖:npmintalmobxmobx-react-lite应用程序的状态已经在Store中创建和管理。我们应用程序的存储看起来像这样:,替换@observable*/makeAutoObservable(this)}}constNotes=newNoteStore()然后我们可以导入笔记并在应用程序的任何地方使用它们。要使组件成为可观察的修改,需要将其包裹在观察者中:import{observer}from'mobx-react-lite'import{notes}from'./NoteStore'constApp=observer(()=>
{notes[0]||"Nonotes"}
)让我们看看它们如何协同工作:importReact,{useState}from'react'import{observer}from"mobx-react-lite"import{makeAutoObservable}from'mobx'classNoteStore{notes=[]createNote(note){this.notes=[...this.notes,note]}constructor(){makeAutoObservable(this)}}constNotes=newNoteStore()constApp=observer(()=>{const[input,setInput]=useState('')const{notes}=NotesfunctiononCreateNote(){Notes.createNote(input)setInput('')}return(
Mynotesapp
CreateNotesetInput(e.target.value)}/>{notes.map(note=>注意:{note})})})exportdefaultApp总结MobX已经存在了一段时间,并且运行良好。和许多其他人一样,我在企业公司的大量在线应用程序中使用过它。最近再次使用后,感觉文档相对于其他一些库略有欠缺。我会自己尝试一下,然后再做决定。XStateXStateDocs[8]代码行数:44XState试图解决现代UI的复杂性并依赖于有限状态机的思想和实现[9]。XState是由DavidKhourshid[10]创建的,自从它发布以来我看到了很多关于它的讨论,所以我一直在关注。这是我在撰写本文之前唯一不熟悉的库。使用之后,我可以肯定地说它的实现与其他库有很大不同。它比其他任何一个都复杂,但状态如何工作的心智模型真的很酷,对开发功能很有帮助,在用它构建了一些演示应用程序后,我觉得它很巧妙。要了解有关XState试图解决的问题的更多信息,请观看DavidKhourshid的视频[11]或这篇我也发现很有趣的帖子[12]。XState在这里不是特别好用,因为它更适合更复杂的状态,但这个简短的介绍至少希望能为您提供一个选项,帮助您深入了解它的工作原理。XState实践要开始使用XState,请安装这些库:npminstallxstate@xstate/react要创建机器,请使用xstate中的Machine实用程序。这是我们将用于Notes应用程序的机器:import{Machine}from'xstate'constnotesMachine=Machine({id:'notes',initial:'ready',context:{notes:[],note:''},states:{ready:{},},on:{"CHANGE":{actions:[assign({note:(_,event)=>event.value})]},"CREATE_NOTE":{actions:[assign({note:"",notes:context=>[...context.notes,context.note]})]}}})我们存储我们在上下文中使用的数据。在这里,我们有一个注释列表和一个输入字段。有两种操作,一种用于创建注释(CREATE_NOTE),另一种用于设置输入(CHANGE)。整个例子:importReactfrom'react'import{useService}from'@xstate/react'import{Machine,assign,interpret}from'xstate'constnotesMachine=Machine({id:'notes',initial:'ready',context:{notes:[],note:''},states:{ready:{},},on:{"CHANGE":{actions:[assign({note:(_,event)=>event.value})]},"CREATE_NOTE":{actions:[assign({note:"",notes:context=>[...context.notes,context.note]})]}}})constservice=interpret(notesMachine).start()exportdefaultfunctionApp(){const[state,send]=useService(service)const{context:{note,notes}}=statereturn(
Mynotesapp
send({type:'CREATE_NOTE'})}>CreateNotesend({type:'CHANGE',value:e.target.value})}/>{notes.map(note=>Note:{note})})}要修改应用程序中的状态,我们使用来自xstate-react的useService挂钩。总之,XState就像劳斯莱斯或状态管理的瑞士军刀。可以做很多事情,但所有功能都会带来额外的复杂性。我希望以后能更好地学习和理解它,以便我可以将它应用于AWS相关问题并参考其架构,但对于小项目我认为它可能太大了。ReduxReactReduxdocs[13]LineofCode:33Redux是整个React生态中最早也是最成功的状态管理库之一。我在很多项目中使用过Redux,它在今天仍然很强大。新的ReduxHooksAPI使使用redux变得更简单、更易于使用。ReduxToolkit还改进了Redux,大大降低了学习曲线。Redux实践在开始使用Redux之前,安装依赖项:npminstall@reduxjs-toolkitreact-redux要使用Redux,您需要创建和配置以下内容:storeReducersAprovider为了帮助解释这一切是如何工作的,我正在实施NotesappinRedux代码中注解:importReact,{useState}from'react'import{Provider,useDispatch,useSelector}from'react-redux'import{configureStore,createReducer,combineReducers}from'@reduxjs/toolkit'functionApp(){const[input,setInput]=useState('')/*useSelector允许您检索要使用的状态,在我们的例子中是notes数组。*/constnotes=useSelector(state=>state.notes)/*dispatch允许我们发送更新信息到store*/constdispatch=useDispatch()functiononCreateNote(){dispatch({type:'CREATE_NOTE',note:input})setInput('')}return(
Mynotesapp
CreateNotesetInput(e.target.value)}/>{notes.map(note=>Note:{note})});}/*这里我们创建一个reducer,它将在`Update触发CREATE_NOTE`操作时的音符数组。*/constnotesReducer=createReducer([],{'CREATE_NOTE':(state,action)=>[...state,action.note]})/*这里我们使用应用程序中的reducers创建thestore*/constreducers=combineReducers({notes:notesReducer})conststore=configureStore({reducer:reducers})functionMain(){return(/*这里,我们在app中使用reducer来创??建store。*/
)}exportdefaultMain总结如果您正在寻找一个拥有庞大社区、大量文档以及大量问题和答案的库,Redux是一个不错的选择。因为它已经诞生很久了,你只要在谷歌上搜索,或多或少都能找到一些相关的答案。在处理异步操作(例如数据获取)时,通常需要添加额外的中间件,这会增加成本和复杂性。对我来说,Redux一开始很难学。一旦我熟悉了这个框架,就很容易使用和理解它。以前对于新开发人员来说有时有点不知所措,但随着ReduxHooks和ReduxToolkit的改进,学习过程变得更加容易,我仍然强烈推荐Redux作为前端选择。ContextContextdocs[14]Lineofcode:31context的优点是不需要安装和依赖其他库,它是React的一部分。使用上下文非常简单,问题通常出现在一些大型或复杂的应用程序中,当您试图管理很多不同的上下文值时,因此您通常必须构建自己的抽象来自己管理这些情况。Context实践创建和使用context,直接从React导入钩子。下面是它的工作原理:/*1.Importthecontexthooks*/importReact,{useState,createContext,useContext}from'react';/*2.Createapieceofcontext*/constNotesContext=createContext();/*3.Setthecontextusingaprovider*//*4.Usethecontext*/const{notes}=useContext(NotesContext);全部代码importReact,{useState,createContext,useContext}来自'react';constNotesContext=createContext();exportdefaultfunctionMain(){const[notes,setNotes]=useState([])functioncreateNote(note){constnotesArray=[...notes,note]setNotes(notesArray)}return();}functionApp(){const{notes,createNote}=useContext(NotesContext);const[input,setInput]=useState('')functiononCreateNote(){createNote(input)setInput('')}return(Mynotesapp
CreateNote<在putvalue={input}onChange={e=>setInput(e.target.value)}/>{notes.map(note=>注:{note})}div>);}总之,context是管理应用程序状态的一种非常可靠和直接的方法,它的API可能不如其他一些库好,但如果您了解如何使用它并且可以在您的应用程序中使用它正确创建数据抽象,那么选择上下文来管理全局状态就不会出错。参考[1]Recoil:https://dev.to/dabit3/react-state-6-ways-2bem?utm_source=digest_mailer&utm_medium=email&utm_campaign=digest_email#recoil[2]MobX:https://dev.to/dabit3/react-state-6-ways-2bem?utm_source=digest_mailer&utm_medium=email&utm_campaign=digest_email#mobx[3]XState:https://dev.to/dabit3/react-state-6-ways-2bem?utm_source=digest_mailer&utm_medium=email&utm_campaign=digest_email#xstate[4]Redux(带钩子):https://dev.to/dabit3/react-state-6-ways-2bem?utm_source=digest_mailer&utm_medium=email&utm_campaign=digest_email#redux[5]上下文:https://dev.to/dabit3/react-state-6-ways-2bem?utm_source=digest_mailer&utm_medium=email&utm_campaign=digest_email#context[6]Recoil文档:https://recoiljs.org/[7]MobXReactLite文档:https://github.com/mobxjs/mobx-react-lite[8]XState文档:https://xstate.js.org/docs/packages/xstate-react/[9]有限状态机:https://en.wikipedia.org/wiki/Finite-state_machine[10]DavidKhourshid:https://twitter.com/DavidKPiano[11]此视频:https://www.youtube.com/watch?v=RqTxtOXcv8Y[12]帖子:https://dev.to/hectorleiva/how-writing-state-machines-made-me-feel-like-a-programmer-2ndc[13]ReactRedux文档:https://react-redux.js.org/[14]上下文文档:https://reactjs.org/docs/hooks-reference.html#usecontext本文转载自微信公众号《秋风手记》,您可以通过以下二维码关注转载文章,请联系秋风手记公众号。