React: Empêcher les rendus avec React.memo et le hook useContext.

Créé le 19 mars 2019  ·  37Commentaires  ·  Source: facebook/react

Vous souhaitez demander une fonctionnalité ou signaler un bug ?

punaise

Quel est le comportement actuel ?

Je ne peux pas compter sur les données de l'API contextuelle en utilisant (le hook useContext) pour éviter les rendus inutiles avec React.memo

Si le comportement actuel est un bogue, veuillez fournir les étapes à reproduire et si possible une démo minimale du problème. Collez le lien vers votre exemple JSFiddle (https://jsfiddle.net/Luktwrdm/) ou CodeSandbox (https://codesandbox.io/s/new) ci-dessous :

React.memo(() => {
const [globalState] = useContext(SomeContext);

render ...

}, (prevProps, nextProps) => {

// How to rely on context in here?
// I need to rerender component only if globalState contains nextProps.value

});

Quel est le comportement attendu ?

Je devrais avoir en quelque sorte accès au contexte dans le rappel du deuxième argument de React.memo pour empêcher le rendu
Ou je devrais avoir la possibilité de renvoyer une ancienne instance du composant de réaction dans le corps de la fonction.

Quelles versions de React, et quel navigateur/OS sont concernés par ce problème ?
16.8.4

Commentaire le plus utile

Cela fonctionne comme prévu. Il y a une discussion plus longue à ce sujet sur https://github.com/facebook/react/issues/14110 si vous êtes curieux.

Disons que pour une raison quelconque, vous avez AppContext dont la valeur a une propriété theme , et que vous souhaitez uniquement restituer certains ExpensiveTree sur les modifications de appContextValue.theme .

TLDR est que pour l'instant, vous avez trois options :

Option 1 (préférée) : contextes fractionnés qui ne changent pas ensemble

Si nous avons juste besoin de appContextValue.theme dans de nombreux composants mais que appContextValue lui-même change trop souvent, nous pourrions séparer ThemeContext de AppContext .

function Button() {
  let theme = useContext(ThemeContext);
  // The rest of your rendering logic
  return <ExpensiveTree className={theme} />;
}

Désormais, tout changement de AppContext ne restituera pas les consommateurs de ThemeContext .

C'est la solution préférée. Alors vous n'avez pas besoin de renflouement spécial.

Option 2 : Divisez votre composant en deux, mettez memo entre les deux

Si, pour une raison quelconque, vous ne pouvez pas séparer les contextes, vous pouvez toujours optimiser le rendu en divisant un composant en deux et en passant des accessoires plus spécifiques à l'intérieur. Vous feriez toujours le rendu de l'extérieur, mais cela devrait être bon marché car il ne fait rien.

function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"
  return <ThemedButton theme={theme} />
}

const ThemedButton = memo(({ theme }) => {
  // The rest of your rendering logic
  return <ExpensiveTree className={theme} />;
});

Option 3 : Un composant avec useMemo intérieur

Enfin, nous pourrions rendre notre code un peu plus détaillé mais le garder dans un seul composant en enveloppant la valeur de retour dans useMemo et en spécifiant ses dépendances. Notre composant serait toujours réexécuté, mais React ne restituerait pas l'arbre enfant si toutes les entrées useMemo sont les mêmes.

function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"

  return useMemo(() => {
    // The rest of your rendering logic
    return <ExpensiveTree className={theme} />;
  }, [theme])
}

Il y aura peut-être d'autres solutions à l'avenir, mais c'est ce que nous avons maintenant.

Cependant, notez que l' option 1 est préférable — si certains contextes changent trop souvent, envisagez de les scinder .

Tous les 37 commentaires

Cela fonctionne comme prévu. Il y a une discussion plus longue à ce sujet sur https://github.com/facebook/react/issues/14110 si vous êtes curieux.

Disons que pour une raison quelconque, vous avez AppContext dont la valeur a une propriété theme , et que vous souhaitez uniquement restituer certains ExpensiveTree sur les modifications de appContextValue.theme .

TLDR est que pour l'instant, vous avez trois options :

Option 1 (préférée) : contextes fractionnés qui ne changent pas ensemble

Si nous avons juste besoin de appContextValue.theme dans de nombreux composants mais que appContextValue lui-même change trop souvent, nous pourrions séparer ThemeContext de AppContext .

function Button() {
  let theme = useContext(ThemeContext);
  // The rest of your rendering logic
  return <ExpensiveTree className={theme} />;
}

Désormais, tout changement de AppContext ne restituera pas les consommateurs de ThemeContext .

C'est la solution préférée. Alors vous n'avez pas besoin de renflouement spécial.

Option 2 : Divisez votre composant en deux, mettez memo entre les deux

Si, pour une raison quelconque, vous ne pouvez pas séparer les contextes, vous pouvez toujours optimiser le rendu en divisant un composant en deux et en passant des accessoires plus spécifiques à l'intérieur. Vous feriez toujours le rendu de l'extérieur, mais cela devrait être bon marché car il ne fait rien.

function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"
  return <ThemedButton theme={theme} />
}

const ThemedButton = memo(({ theme }) => {
  // The rest of your rendering logic
  return <ExpensiveTree className={theme} />;
});

Option 3 : Un composant avec useMemo intérieur

Enfin, nous pourrions rendre notre code un peu plus détaillé mais le garder dans un seul composant en enveloppant la valeur de retour dans useMemo et en spécifiant ses dépendances. Notre composant serait toujours réexécuté, mais React ne restituerait pas l'arbre enfant si toutes les entrées useMemo sont les mêmes.

function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"

  return useMemo(() => {
    // The rest of your rendering logic
    return <ExpensiveTree className={theme} />;
  }, [theme])
}

Il y aura peut-être d'autres solutions à l'avenir, mais c'est ce que nous avons maintenant.

Cependant, notez que l' option 1 est préférable — si certains contextes changent trop souvent, envisagez de les scinder .

Ces deux options annuleront le rendu des enfants si le thème n'a pas changé.

@gaearon Les boutons sont-ils les enfants ou les boutons rendent-ils les enfants ? Il me manque un peu de contexte sur la façon dont ils sont utilisés.

L'utilisation de l'option 2 unstable_Profiler déclenchera toujours les rappels onRender mais n'appellera pas la logique de rendu réelle. Peut-être que je fais quelque chose de mal ? ~ https://codesandbox.io/s/kxz4o2oyoo~ https://codesandbox.io/s/00yn9yqzjw

J'ai mis à jour l'exemple pour être plus clair.

L'utilisation de l'option 2 unstable_Profiler déclenchera toujours les rappels onRender mais n'appellera pas la logique de rendu réelle. Peut-être que je fais quelque chose de mal ? https://codesandbox.io/s/kxz4o2oyoo

C'est exactement le but de cette option. :-)

Peut-être qu'une bonne solution pour cela serait d'avoir la possibilité de "prendre" le contexte et le composant de rendu uniquement si le rappel est renvoyé vrai, par exemple :
useContext(ThemeContext, (contextData => contextData.someArray.length !== 0 ));

Le principal problème avec les crochets que j'ai rencontrés est que nous ne pouvons pas gérer depuis l'intérieur d'un crochet ce qui est renvoyé par un composant - pour empêcher le rendu, renvoyer la valeur mémorisée, etc.

Si nous le pouvions, ce ne serait pas composable.

https://overreacted.io/why-isnt-xa-hook/#not -a-hook-usebailout

Option 4 : ne pas utiliser le contexte pour la propagation des données mais l'abonnement aux données. Utilisez useSubscription (car il est difficile d'écrire pour couvrir tous les cas).

Il existe un autre moyen d'éviter le re-rendu.
"Vous devez faire monter le JSX d'un niveau hors du composant de re-rendu pour qu'il ne soit pas recréé à chaque fois"

Plus d'infos ici

Peut-être qu'une bonne solution pour cela serait d'avoir la possibilité de "prendre" le contexte et le composant de rendu uniquement si le rappel est renvoyé vrai, par exemple :
useContext(ThemeContext, (contextData => contextData.someArray.length !== 0 ));

Le principal problème avec les crochets que j'ai rencontrés est que nous ne pouvons pas gérer depuis l'intérieur d'un crochet ce qui est renvoyé par un composant - pour empêcher le rendu, renvoyer la valeur mémorisée, etc.

Au lieu d'un vrai/faux ici... pourrions-nous fournir une fonction basée sur l'identité qui nous permettrait de sous-ensemble les données du contexte ?

const contextDataINeed = useContext(ContextObj, (state) => state['keyICareAbout'])

où useContext n'apparaîtrait pas dans ce composant à moins que le résultat du sélecteur fn ne soit différent du point de vue de l'identité du résultat précédent de la même fonction.

trouvé cette bibliothèque que cela peut être la solution pour Facebook à intégrer avec des crochets https://blog.axlight.com/posts/super-performant-global-state-with-react-context-and-hooks/

Il existe un autre moyen d'éviter le re-rendu.
"Vous devez faire monter le JSX d'un niveau hors du composant de re-rendu pour qu'il ne soit pas recréé à chaque fois"

Plus d'infos ici

Le problème est qu'il peut être coûteux de restructurer l'arborescence des composants juste pour empêcher un nouveau rendu de haut en bas.

@fuleinist En

@gaearon Je ne sais pas s'il me manque quelque chose, mais j'ai essayé vos deuxième et troisième options et elles ne fonctionnent pas correctement. Je ne sais pas s'il s'agit uniquement d'un bogue d'extension chrome ou s'il existe un autre problème. Voici mon exemple simple de formulaire, où je vois le rendu des deux entrées. Dans la console, je vois que le mémo fait son travail mais DOM est restitué tout le temps. J'ai essayé 1000 éléments et l'événement onChange est vraiment lent, c'est pourquoi je pense que memo() ne fonctionne pas correctement avec le contexte. Merci pour tout conseil :

Voici une démo avec 1000 éléments/zones de texte. Mais dans cette démo, les outils de développement n'affichent pas le nouveau rendu. Il faut télécharger les sources sur local pour le tester : https://codesandbox.io/embed/zen-firefly-d5bxk

import React, { createContext, useState, useContext, memo } from "react";

const FormContext = createContext();

const FormProvider = ({ initialValues, children }) => {
  const [values, setValues] = useState(initialValues);

  const value = {
    values,
    setValues
  };

  return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
};

const TextField = memo(
  ({ name, value, setValues }) => {
    console.log(name);
    return (
      <input
        type="text"
        value={value}
        onChange={e => {
          e.persist();
          setValues(prev => ({
            ...prev,
            [name]: e.target.value
          }));
        }}
      />
    );
  },
  (prev, next) => prev.value === next.value
);

const Field = ({ name }) => {
  const { values, setValues } = useContext(FormContext);

  const value = values[name];

  return <TextField name={name} value={value} setValues={setValues} />;
};

const App = () => (
  <FormProvider initialValues={{ firstName: "Marr", lastName: "Keri" }}>
    First name: <Field name="firstName" />
    <br />
    Last name: <Field name="lastName" />
  </FormProvider>
);

export default App;

image

D'un autre côté cette approche sans contexte fonctionne correctement, toujours en débogage c'est plus lent que ce à quoi je m'attendais mais au moins le rendu est ok

import React, { useState, memo } from "react";
import ReactDOM from "react-dom";

const arr = [...Array(1000).keys()];

const TextField = memo(
  ({ index, value, onChange }) => (
    <input
      type="text"
      value={value}
      onChange={e => {
        console.log(index);
        onChange(index, e.target.value);
      }}
    />
  ),
  (prev, next) => prev.value === next.value
);

const App = () => {
  const [state, setState] = useState(arr.map(x => ({ name: x })));

  const onChange = (index, value) =>
    setState(prev => {
      return prev.map((item, i) => {
        if (i === index) return { name: value };

        return item;
      });
    });

  return state.map((item, i) => (
    <div key={i}>
      <TextField index={i} value={item.name} onChange={onChange} />
    </div>
  ));
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

image

@marrkeri Je ne vois rien de mal dans le premier extrait de code. Le composant mis en évidence dans les outils de développement est le Field qui utilise le contexte, et non le TextField qui est un composant mémo et implémente la fonction areEqual.

Je pense que le problème de performances dans l'exemple codesandbox vient des 1000 composants qui utilisent le contexte. Refactorisez-le en un composant qui utilise le contexte, disons Fields , et renvoyez à partir de ce composant (avec une carte) un TextField pour chaque valeur.

@marrkeri Je ne vois rien de mal dans le premier extrait de code. Le composant mis en évidence dans les outils de développement est le Field qui utilise le contexte, et non le TextField qui est un composant mémo et implémente la fonction areEqual.

Je pense que le problème de performances dans l'exemple codesandbox vient des 1000 composants qui utilisent le contexte. Refactorisez-le en un composant qui utilise le contexte, disons Fields , et renvoyez à partir de ce composant (avec une carte) un TextField pour chaque valeur.

Comme vous l'avez dit, j'étais sous la même pensée que devrait être restitué à chaque fois mais ( ) uniquement lorsque la valeur est modifiée. Mais ce ne sont probablement que des problèmes d'outils de développement car j'ai ajouté du remplissage et au lieu de ça est restitué. Vérifiez cette image
image

image

Je n'ai pas compris votre deuxième point sur la refactorisation en un seul composant . Pourriez-vous faire un instantané svp ? Et que pensez-vous du nombre maximum affiché de qui sont ok sans retard ? Est-ce que 1000 c'est trop ?

@marrkeri Je suggérais quelque chose comme ça : https://codesandbox.io/s/little-night-p985y.

Est-ce la raison pour laquelle react-redux a dû cesser d' utiliser les avantages de l'API de contexte stable et de transmettre l'état actuel au contexte lors de la migration vers les Hooks ?

On dirait donc qu'il y a

Option 4 : passez une fonction d'abonnement en tant que valeur de contexte, comme à l'ère du contexte hérité

Cela peut être la seule option si vous ne contrôlez pas les utilisations (nécessaire pour les options 2-3) et ne pouvez pas énumérer tous les sélecteurs possibles (nécessaire pour l'option 1), mais que vous souhaitez tout de même exposer une API Hooks

const MyContext = createContext()
export const Provider = ({children}) => (
  <MyContext.provider value={{subscribe: listener => ..., getValue: () => ...}}>
    {children}
  </MyContext.provider>
)

export const useSelector = (selector, equalityFunction = (a, b) => a === b) => {
  const {subscribe, getValue} = useContext(MyContext)
  const [value, setValue] = useState(getValue())
  useEffect(() => subscribe(state => {
      const newValue = selector(state)
      if (!equalityFunction(newValue, value) {
        setValue(newValue)
      }
  }), [selector, equalityFunction])
}

@Hypnosphi : nous avons cessé de transmettre l'état du magasin en contexte (l'implémentation v6) et sommes revenus aux abonnements directs au magasin (l'implémentation v7) en raison d'une combinaison de problèmes de performances et de l'incapacité de renflouer les mises à jour causées par le contexte (ce qui l'a rendu impossible de créer une API de hooks React-Redux basée sur l'approche v6).

Pour plus de détails, consultez mon article The History and Implementation of React-Redux .

J'ai lu le fil de discussion, mais je me demande toujours : les seules options disponibles aujourd'hui pour un rendu conditionnel en cas de changement de contexte, "Options 1 2 3 4" répertoriées ci-dessus ? Est-ce que quelque chose d'autre est en préparation pour résoudre officiellement ce problème ou les « 4 solutions » sont-elles considérées comme suffisamment acceptables ?

J'ai écrit dans l'autre fil, mais juste au cas où. Voici une solution de contournement _non officielle_.
proposition useContextSelector et bibliothèque use-context-selector dans l'espace utilisateur.

Honnêtement, cela me fait penser que le framework n'est tout simplement pas prêt à entrer pleinement dans les fonctions et les crochets comme nous sommes encouragés. Avec les classes et les méthodes de cycle de vie, vous aviez une manière ordonnée de contrôler ces choses et maintenant avec les crochets, c'est une syntaxe bien pire et moins lisible

L'option 3 ne semble pas fonctionner. Est-ce que je fais quelque chose de mal ? https://stackblitz.com/edit/react-w8gr8z

@Martin , je ne suis pas d'accord avec ça.

Le modèle de crochet peut être lisible avec une documentation et un code bien organisés
la structure et les classes React et le cycle de vie sont tous remplaçables par fonctionnels
équivalents.

Malheureusement, le modèle réactif ne peut pas être atteint par React via
soit des classes React, soit des hooks.

Le sam. 11 janv. 2020 à 9h44 Martin Genev [email protected]
a écrit:

Honnêtement, cela me fait penser que le cadre n'est tout simplement pas prêt à partir
pleinement dans les fonctions et les crochets comme nous sommes encouragés. Avec des cours
et les méthodes de cycle de vie, vous aviez une manière ordonnée de contrôler ces choses et
maintenant avec les hooks c'est une syntaxe bien pire et moins lisible

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/facebook/react/issues/15156?email_source=notifications&email_token=AAI4DWUJ7WUXMHAR6F2KVXTQ5D25TA5CNFSM4G7UEEO2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNIVWXHJKLODNEMG7UEEO2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNIVWXHJKLOPNP
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/AAI4DWUCO7ORHV5OSDCE35TQ5D25TANCNFSM4G7UEEOQ
.

@mgenev L' option 3 empêche le rendu de l'enfant ( <ExpensiveTree /> , le nom parle de lui-même)

@Hypnosphi merci, c'était correct.
https://stackblitz.com/edit/react-ycfyye

J'ai réécrit et maintenant les composants de rendu (affichage) réels ne sont pas rendus à nouveau, mais tous les conteneurs (contextuels connectés) sont rendus lors de tout changement d'accessoire sur le contexte, peu importe s'il est utilisé dans eux. Maintenant, la seule option que je peux voir est de commencer à diviser les contextes, mais certaines choses sont vraiment globales et s'enroulent au plus haut niveau et un changement sur n'importe quel accessoire provoquera le déclenchement de tous les conteneurs dans l'ensemble de l'application, je ne ' Je ne comprends pas en quoi cela peut être bon pour les performances...

Existe-t-il quelque part un bon exemple de la façon de procéder de manière performante ? Les docs officiels sont vraiment limités

Vous pouvez essayer mon option 4, qui est essentiellement ce que fait react-redux en interne
https://github.com/facebook/react/issues/15156#issuecomment -546703046

Pour implémenter la fonction subscribe , vous pouvez utiliser quelque chose comme Observables ou EventEmitter, ou simplement écrire vous-même une logique d'abonnement de base :

function StateProvider({children}) {
  const [state, dispatch] = useReducer(reducer, initialState)
  const listeners = useRef([])
  const subscribe = listener => {
    listeners.current.push(listener)
  }
  useEffect(() => {
    listeners.current.forEach(listener => listener(state)
  }, [state])

  return (
    <DispatchContext.Provider value={dispatch}>
      <SubscribeContext.Provider value={{subscribe, getValue: () => state}}>
          {children}      
      </SubscribeContext.Provider>
    </DispatchContext.Provider>
  );
}

Pour ceux qui peuvent avoir des intérêts, voici la comparaison de différentes bibliothèques quelque peu liées à ce sujet.
https://github.com/dai-shi/will-this-react-global-state-work-in-concurrent-mode

Mon dernier effort est de vérifier la prise en charge du branchement d'état avec useTransition qui serait important dans le prochain mode simultané.
Fondamentalement, si nous utilisons l'état et le contexte de React de manière normale, ce n'est pas grave. (sinon, nous avons besoin d'une astuce, par exemple, ce .)

Merci @dai-shi j'aime beaucoup vos packages et je cherche à les adopter.

@dai-shi salut, je viens de trouver votre react-tracked et elle a l'air vraiment bien si elle résout les problèmes de performances avec les contextes comme il le promet. Est-il toujours réel ou mieux d'utiliser autre chose ? Ici, je vois un bon exemple de son utilisation, il montre également comment créer un niveau middleware avec use-reducer-async https://github.com/dai-shi/react-tracked/blob/master/examples/12_async/src/store .ts Merci pour cela. Actuellement, j'ai fait quelque chose de similaire en utilisant useReducer , en enveloppant dispatch avec le mien pour un middleware asynchrone et en utilisant Context mais en m'inquiétant des futurs problèmes de performances de rendu en raison de l'enveloppement des contextes.

@bobrosoft react-tracked est assez stable, je dirais (en tant que produit de développement à coup sûr). Les commentaires sont les bienvenus et c'est ainsi qu'une bibliothèque serait améliorée. Actuellement, il utilise en interne une fonctionnalité non documentée de React, et j'espère que nous serons en mesure de le remplacer par une meilleure primitive à l'avenir. use-reducer-async est presque comme un simple sucre de syntaxe qui ne se tromperait jamais.

Ce HoC a fonctionné pour moi :
````
importer React, { useMemo, ReactElement, FC } de 'react' ;
importer réduire à partir de « lodash/réduire » ;

type Selector = (context: any) => any;

interface SelectorObject {
}

const withContext = (
Composant : FC,
Contexte : tout,
sélecteurs : SelectorObject,
): FC => {
return (props: any): ReactElement => {
const Consommateur = ({ contexte } : tout) : ReactElement => {
const contextProps = réduire(
sélecteurs,
(acc : any, selector : Selector, key : string) : any => {
valeur const = sélecteur(contexte);
acc[clé] = valeur ;
retour acc;
},
{},
);
return useMemo(
(): ReactElement => ,
[...Object.values(props), ...Object.values(contextProps)],
);
} ;
retourner (

{(contexte : n'importe lequel) : ReactElement => }

);
} ;
} ;

exportation par défaut withContext ;
````

exemple d'utilisation :

export default withContext(Component, Context, { value: (context): any => context.inputs.foo.value, status: (context): any => context.inputs.foo.status, });

cela pourrait être considéré comme l'équivalent Context de redux mapStateToProps

J'ai fait un hoc presque très similaire à connect() en redux

const withContext = (
  context = createContext(),
  mapState,
  mapDispatchers
) => WrapperComponent => {
  function EnhancedComponent(props) {
    const targetContext = useContext(context);
    const { ...statePointers } = mapState(targetContext);
    const { ...dispatchPointers } = mapDispatchers(targetContext);
    return useMemo(
      () => (
        <WrapperComponent {...props} {...statePointers} {...dispatchPointers} />
      ),
      [
        ...Object.values(statePointers),
        ...Object.values(props),
        ...Object.values(dispatchPointers)
      ]
    );
  }
  return EnhancedComponent;
};

Mise en œuvre :

const mapActions = state => {
  return {};
};

const mapState = state => {
  return {
    theme: (state && state.theme) || ""
  };
};
export default connectContext(ThemeContext, mapState, mapActions)(Button);


Mise à jour : en fin de compte, je suis passé à EventEmitter pour des données granulaires à changement rapide avec des écouteurs dynamiques (sur le mouvement de la souris). J'ai réalisé que j'étais c'était le meilleur outil pour le travail. Le contexte est idéal pour le partage général des données, mais pas à des taux de rafraîchissement élevés.

Ne s'agit-il pas de souscrire ou de ne pas souscrire déclarativement au contexte ? Envelopper conditionnellement un composant dans un autre qui utilise useContext().

La principale exigence est que le composant interne ne puisse pas avoir d'état, car il s'agira effectivement d'une instance différente en raison du branchement. Ou, peut-être que vous pouvez pré-rendu le composant puis utiliser cloneElement pour mettre à jour les accessoires.

Certains composants n'ont rien à voir avec le contexte dans son rendu mais doivent "juste lire une valeur" à partir de celui-ci. Qu'est-ce que je rate?
context

Context._currentValue est-

J'essaie d'abonner des composants à des contextes qui sont aussi peu coûteux à rendre que possible. Mais ensuite, je me suis retrouvé à passer des accessoires comme à l'ancienne avec un code sphagetti ou à utiliser un mémo pour éviter de souscrire aux mises à jour alors qu'il n'y a rien de logique avec les mises à jour. Les solutions mémo sont bonnes lorsque le rendu de votre composant dépend des contextes mais sinon ...

@vamshi9666 l' avez-vous beaucoup utilisé ? avez-vous pu constater les avantages/inconvénients de votre approche ? Je l'aime beaucoup. J'aime la similitude avec le redux mais aussi la façon dont cela vous permet d'écrire librement la gestion de l'état de l'application et la logique en tant que contexte

J'ai trouvé https://recoiljs.org/ une bonne solution à ce problème. Je pense que ce serait génial si vous l'intégriez dans React.

@vamshi9666 l' avez-vous beaucoup utilisé ? avez-vous pu constater les avantages/inconvénients de votre approche ? Je l'aime beaucoup. J'aime la similitude avec le redux mais aussi la façon dont cela vous permet d'écrire librement la gestion de l'état de l'application et la logique en tant que contexte

Je ne l'ai utilisé qu'à un seul endroit et mon objectif initial est d'isoler la gestion d'état de jsx mais aussi de ne pas créer un pas de passe-partout. Ainsi, lorsque j'ai étendu la fonctionnalité de mutations, cela ressemblait beaucoup au modèle de réducteur et de créateur d'action de redux. Ce qui est encore mieux. mais je ne vois pas l'intérêt de réinventer quelque chose, alors que c'est déjà là.

Cette page vous a été utile?
0 / 5 - 0 notes