Site icon Blog ARC Optimizer

Comment passer de Redux à Recoil


Comme Redux, Recoil est une bibliothèque de gestion d'état dans React. Regardons les différences et comment effectuer le changement lorsque vous êtes prêt.

La gestion d'un état complexe dans React peut parfois être difficile, c'est pourquoi certains d'entre nous utilisent Redux ou des bibliothèques similaires comme MobX pour gérer l'état dans React. [19659003] Recoil est une autre bibliothèque de gestion d'état qui est étroitement modélisée vers l'API Hooks de React. Il vous permet de définir l'état partagé comme atomes et l'état calculé auquel il se réfère en tant que sélecteurs . Si vous voulez en savoir plus sur les limitations auxquelles l'équipe de Facebook a été confrontée et comment ils ont essayé de les résoudre avec recul, vous pouvez regarder cette vidéo .

Une note importante: bien que de nombreuses entreprises, dont Facebook, utilisent Recoil , il est techniquement dans un état expérimental, et son API et ses fonctionnalités peuvent changer.

Dans cet article, je vais vous montrer comment passer de Redux à Recoil et en cours de route comparer les différences. Je vais travailler avec l'exemple TodoMVC du référentiel GitHub de Redux . Vous pouvez télécharger le fichier zip en utilisant ce lien que j'ai créé pour vous 😉. Voici comment fonctionne l'application:

Configuration de Recoil

La ​​première étape pour utiliser une bibliothèque JavaScript est de l'ajouter au projet. Vous pouvez ajouter une référence à l'aide de la balise HTML ou l'installer via npm. Puisque vous avez téléchargé un projet de style npm, installez Recoil en exécutant npm install recoil ou yarn add recoil .

Similaire à l'utilisation de Redux où nous enveloppons notre composant racine avec le [19659010]nous allons le remplacer par afin que l'état Recoil soit disponible pour les composants enfants.

Ouvrez src / index.js et importez le RecoilRoot module.

 import   { RecoilRoot }   from   "recoil" ; 

Puis mettez à jour la fonction de rendu comme suit:

 render  (
   < RecoilRoot > 
     < App  / > 
   < /  RecoilRoot > 
  document .  getElementById  ( "root" ) 
) ; 

Définition et mise à jour de l'état

Pour représenter un état, vous déclarez ce qu'on appelle un atome . Puisque nous voulons stocker une liste de tâches, nous allons créer un atome avec un état par défaut ou initial. Créez un nouveau répertoire recoil et ajoutez un nouveau fichier nommé todos avec le contenu suivant.

 import   { atom }   from [19659016] "recoil" ; 

 export   const  todos  =   atom  ( {
  clé :   "todos" 
   default :   [] 
} ) ; 

Ouvrez maintenant le composant / Header.js et mettez-le à jour avec ce code:

 import  React  from   "react" ; 
 import  TodoTextInput  de   "./ TodoTextInput" ; 
 import   { useSetRecoilState }   from   "recoil" ; 
 import   { todos }   from   "../ recoil / todos" ; 

 const   Header   =   () )   =>   {
   const  setTodos  =   useSetRecoilState  ( todos ) ; 

   const   save   =   ( texte )   =>   {
     if   ( text .  length ! = = [19659091] 0 )   {
       setTodos  ( ( todos )   =>   [
         ...  todos 
         {
          id :  Date .  now  () 
          texte 
          complété :   false 
        } 
      ] ) ; 
    } 
  } ; 

   return [19659014] (
     < header className  =  "header" > 
       < h1 >  todos  < /  h1 > 
       < TodoTextInput
        nouveauTodo
        onSave  =  { save } 
        placeholder  =  "Que faut-il faire?" 
       / > 
     < /  header > 
  ) ; [19659031]} ; 

 export   default  Header ; 

Ce composant affiche une entrée de texte pour collecter de nouveaux todos et les enregistrer. Pour ajouter un nouveau todo, nous avons besoin d'une fonction qui mettra à jour le contenu de l'état todos . Nous avons utilisé le hook useSetRecoilState () pour obtenir une fonction setter qui est utilisée dans la fonction save () . À la ligne 11, nous avons utilisé la forme updater de la fonction setter afin de pouvoir créer une nouvelle liste basée sur les anciennes tâches. C'est tout ce que nous devons faire pour être en mesure de collecter et de stocker des éléments à faire.

Si vous comparez cela à Redux, vous devrez créer des créateurs et des réducteurs d'action pour mettre à jour un élément d'état, puis connecter le composant au magasin Redux et expédier les actions. Dans Recoil, vous définissez un atome pour contenir des données, puis utilisez une API hook pour interagir avec ces données. Si vous êtes nouveau dans React et que vous comprenez l'API hooks, il devrait être rapide à saisir Recoil car il est étroitement modélisé à l'API de React, contrairement à Redux où vous auriez besoin de comprendre son style de flux de données unidirectionnel.

Derived State [19659138] La prochaine section de l'application à mettre à jour est le composant . Il rend une entrée pour marquer toutes les tâches comme terminées, ainsi que deux composants supplémentaires auxquels nous reviendrons plus tard. Alors, ouvrez components / MainSection.js et mettez-le à jour avec le code ci-dessous:
 import  React  from   "react" ; 
 import   ] { useRecoilValue  useRecoilState }   from   "recoil" ; 
 import  Footer  from   "./ Footer "; 
 import  VisibleTodoList  from  " ../ containers / VisibleTodoList "; 
 import   { completedTodoCount  todos }   from   "../ recoil / todos" ; 

 const   MainSection   =   ()   = >   {
   const  completedCount  =   useRecoilValue  ( completedTodoCount ) ; 
   const   [ todoList  setTodoList ]   =   useRecoilState [19659017] ( todos ) ; 
   const  todosCount  =  todoList .  length ; 

   const   clearCompleted   =   ()   =>   {
     setTodoList  ( ( previousTodos )   => 
      previousTodos .  filter  ( ( todo )   =>  todo .  completed  === [19659105] false ) 
    ) ; 
  } ; 

   const   completeAllTodos   =   ()   => 
     setTodoList  ( ( previousTodos )   =>   {
       const  areAllMarked  =  previousTodos .  chaque  ( ( todo )   =>  todo .  completed ) ; 
       return  previousTodos .  carte  ( ( todo )   =>   ( {
         ...  todo 
        terminé :  !  areAllMarked 
      } ) ) ; 
    } ) ; 

   return [19659014] (
     < section className  =  "main" > 
       {! !  todosCount  &&   ( 
         < span > 
           < input
            className  =  "tout basculer" 
            type  =  "case à cocher" 
            vérifié  =  { completedCount  ===  todosCount } 
            lecture seulement
           / > 
           < label onClick  =  { completeAllTodos }   / > 
         < /  span > 
      ) } 
       < VisibleTodoList  / > 
       {! !  todosCount  &&   (
         < Pied de page
          CompleteCount  =  { completedCount } 
          activeCount  =  { todosCount  -  completedCount } 
          onClearCompleted  =  { clearCompleted } 
         / > 
      ) } 
     < /  section > [19659113]) ; 
} ; 

 export   default  MainSection ; 

Ce que nous avons fait ici, c'est qu'au lieu de nous connecter à Redux et d'appeler mapStateToProps et mapDispatchToProps nous avons utilisé deux crochets Recoil, qui sont useRecoilValue et useRecoilState . La fonction useRecoilValue () est utilisée pour lire le contenu d'un état; dans notre cas, c'est completedTodoCount . Nous voulons obtenir l'état todos et également pouvoir le mettre à jour. Pour cela, nous utilisons useRecoilState () pour lire todos et obtenir une fonction pour le mettre à jour. Nous avons deux fonctions, clearCompleted () et completeAllTodos () qui sont utilisées pour mettre à jour l'état.

Nous devons définir l'état completedTodoCount . Cela doit être calculé à partir de l'état todos . Pour cela, nous allons créer ce que l’on appelle le sélecteur dans Recoil. Ouvrez recoil / todos.js et importez le sélecteur du package Recoil.

 import   { atom  selector }   from   "recoil" ; 

Puis définissez le sélecteur comme vous le voyez ci-dessous:

 export   const  completedTodoCount  =   selector  (  {
  clé :   "completedTodoCount" 
   get :   ( {  get  } )   => [19659014] {
     const  list  =   get  ( todos ) ; 

     return  list .  réduire  (
       ( count  todo )   =>   ( todo .  completed ?  compte  +   1  :  compte ) 
       0 
    ) ; 
  } 
 } ) ; 

Pour définir un sélecteur, vous appelez la fonction selector () avec un objet qui contient le nom de l'état et un get () qui calculera et retournera une valeur. Cette fonction reçoit un objet qui a une fonction get () qui peut être utilisée pour récupérer des données d'autres atomes ou sélecteurs.

Filtrage de Todos

À ce stade, j'ai couvert la plupart des bases de Recoil et vous pouvez voir en quoi il est différent de Redux mais étroitement modélisé vers l'API Hooks de React. Le reste de cet article ajoutera simplement du code pour rendre l'application pleinement fonctionnelle à l'aide de Recoil.

Le composant suivant sur lequel nous allons travailler est le composant . Ouvrez containers / FilterLink.js et mettez à jour le fichier avec le code ci-dessous:

 import  React  from   "react" ; 
 import   { useRecoilState }   de   "recoil" ; 
 import  Link  from   "../ components / Link" ; 
 import   { visibilitéFilter }   from   "../ recoil / todos" ; 

 export   default   ( { filtre  enfants } )   =>   {
   const   [ visibilité  setVisibilityFilter ]   =   useRecoilState  ( visibilitéFilter ) ; 
   const   setFilter   =   () [19659074] =>   setVisibilityFilter  ( filter ) ; 

   return   (
     < Lien
      actif  =  { filtre  ===  visibilité } 
      setFilter  =  { setFilter } 
      enfants  =  { enfants } 
     / > 
  ) ; 
} ; 

Nous rendons ici le composant qui rendra l'entrée utilisée pour sélectionner comment filtrer les todos qui seront affichés. Nous avons utilisé un nouvel état que nous n’avons pas encore créé, nous allons donc l’ajouter. Ouvrez recoil / todos.js et ajoutez la fonction ci-dessous:

 import   {
  SHOW_ALL 
  SHOW_COMPLETED 
  SHOW_ACTIVE 
}   from   "../ constants / TodoFilters" ; 

 export   const  visibilitéFilter  =   atom  ] ( {
  clé :   "visibilitéFilter" 
   default :  SHOW_ALL 
} ) ; 

Display Todos [19659007] La prochaine chose à faire est d'afficher les todos en fonction du filtre défini. Pour cela, nous allons ajouter un nouveau sélecteur et mettre à jour le composant . Tant que vous avez encore recoil / todos.js ouvert, ajoutez le sélecteur ci-dessous.
 export   const  filteredTodos  =   selector  ( ] {
  clé :   "filteredTodos" 
   get :   ( {  get  } )   => [19659014] {
     const  filter  =   get  ( visibilitéFilter ) ; 
     const  list  =   get  ( todos ) ; 

     switch   ( filter )   {
       case  SHOW_COMPLETED : [19659427] retour  liste .  filtre  ( ( t )   =>  t .  terminé  ) ; 
       cas  SHOW_ACTIVE : 
         return  list .  filter  ( ( t ) [19659074] =>  !  t .  terminé ) ; 
       default : 
         return  list ; [19659112]} 
  } [19659017]
} ) ; 

Open containers / VisibleTodoList.js et mettez à jour le fichier avec le code ci-dessous:

 import  React  from   "react" ; 
 import  TodoList  from   "../ components / TodoList" ; 
 import   { filteredTodos  todos }   from   "../ recoil / todos" ; 
 import   { useRecoilValue  useSetRecoilState }   from   "recoil" ; 

 const   VisibleTodoList   =   ()   =>   {[19659047] const  filteredTodoList  =   useRecoilValue  ( filteredTodos ) ; 
   const  setTodos  =  useSetRecoilate (19659042] useSetRecoilate (19659017)  todos ) ; 

   const   completeTodo   = [19659014] ( todoId )   =>   {
     setTodos  ( ( previousTodos )   => 
      previousTodos .  carte  ( ( todo )   => 
        todo .  id  ===  todoId ?   {  ...  todo  completed : [19659074]!  todo .  completed }  :  todo
      ) 
    ) ; 
  } ; 

   const   deleteTodo   =   ( todoId )   => [19659014] {
     setTodos  ( ( previousTodos )   => 
      previousTodos .  filter  ( ( todo )   =>  todo .  id ! ==  todoId ) 
    ) ; 
  } ; 

   const   editTodo   =   ( todoId  text )   =>   {
     setTodos  ( ( previousTodos )   => 
      previousTodos .  carte  ( ( todo )   => 
        todo .  id  ===  todoId ?   {  ...  todo  text } [19659014]:  todo
      ) 
    ) ; 
  } ; 

   return   (
     < TodoList
      filteredTodos  =  { filteredTodoList } 
      actions  =  { { completeTodo  deleteTodo  editTodo } } 
     / > [19659113]) ; 
} ; 

 export   default  VisibleTodoList ; 

Ici, nous avons ajouté trois fonctions pour supprimer un todo, le mettre à jour ou le marquer comme terminé. Nous pouvons considérer ces fonctions comme une combinaison d'actions et de fonctions réductrices dans Redux. J'ai décidé de placer les fonctions dans le même fichier que le composant qui en a besoin, mais vous pouvez les extraire dans un fichier séparé si vous le souhaitez.

À ce stade, nous avons mis à jour l'application pour utiliser Recoil au lieu de Redux. La dernière chose à faire est de mettre à jour components / App.js . Ouvrez ce fichier et modifiez l'instruction d'importation pour les composants

et .

 import  Header  from   "./ Header" ; 
 import  MainSection  from   "./ MainSection" ; 

Et voilà, une application todo mise à jour de l'utilisation de Redux to Recoil.

Conclusion

Déplacer cette application de Redux vers Recoil a été moins compliqué que je ne l’aurais imaginé. Je suppose que ce ne sera pas le cas pour toutes vos applications, en fonction de la façon dont vous avez conçu votre état Redux et de quelques autres facteurs. Mais je pense qu’elle est assez facile à utiliser pour les nouvelles applications, car elle est calquée sur l’API React que vous connaissez bien.

Pour en savoir plus sur Recoil, consultez recoiljs.org . Vous pouvez trouver l'application complète avec le code source sur GitHub .





Source link
Quitter la version mobile