1
votes

Utilisation du hook useState dans useEffect sur history.listen

Je rencontre des problèmes avec useState lorsque j'écoute les modifications de history dans useEffect .

Lorsque le chemin d'accès code> change, setState est lancé mais ensuite l ' state est rajouté.

Par exemple, j'ai un drapeau composant qui recueille des groupes de notifications, mais lors du changement de chemin , je souhaite que tous les indicateurs soient rejetés et supprimés de state. composant flag

const DefaultState: InterfaceState = {
  otherStateExample: false,
  flags: []
};

export const GlobalConsumer = createContext({
  contextData: DefaultState,
  addFlag: (flagData: any) => {},
  dismissFlag: () => {},
  dismissAllFlags: () => {}
});

export const GlobalProvider = ({ children }: InterfaceProps) => {
  const [state, setState] = useState<InterfaceState>({
    ...DefaultState
  });

  return (
    <GlobalConsumer.Provider
      value={{
        contextData: state,
        addFlag: (flagData: any) => {
          setState({ ...state, flags: [flagData].concat(state.flags) });
        },
        dismissFlag: () => {
          setState({ ...state, flags: state.flags.slice(1) });
        },
        dismissAllFlags: () => {
          setState({ ...state, flags: [] });
        }
      }}
    >
      {children}
    </GlobalConsumer.Provider>
  );
};

L'historique est utilisé depuis import {withRouter} depuis 'react-router-dom'

L'état et la fonction de ignoreAllFlags sont affichés dans un composant createContext sous la forme

const PageFlag = ({ history }: InterfaceProps) => {
const { contextData, dismissFlag, dismissAllFlags } = useContext(GlobalConsumer);

  useEffect(() => {
    history.listen(() => {
      dismissAllFlags();
    });
  });

  return (
    <>
      <FlagGroup onDismissed={dismissFlag}>
        {contextData.flags.map((flag, index) => (
          <Flag key={index} {...flag} />
        ))}
      </FlagGroup>
    </>
  );
};

Le problème survient, où chemin d'accès change, ignoreAllFlags utilise setState pour définir indicateurs comme [] mais ajoute ensuite revenir à l'état précédent avec les flags .

Comment puis-je supprimer tous les drapeaux mais souvenez-vous de l ' état actuel pour les autres articles?


2 commentaires

pouvez-vous fournir un code et une boîte?


Il semble que votre GlobalProvider pourrait être démonté entre les changements de chemin avec son état par défaut.


3 Réponses :


6
votes

Il vous manque le deuxième paramètre d'entrée sur useEffect () , ce qui va entraîner la lecture de l'auditeur à chaque rendu.

Cela devrait ressembler à ceci, notez que vous ne devriez pas non plus avoir besoin de la fonction interne.

useEffect(() => {
  history.listen(dismissAllFlags)
}, []);


4 commentaires

l'histoire devrait être une dépendance


Bien que techniquement correct, l'objet historique ne change jamais, il n'y a donc aucun avantage à vérifier quelque chose qui ne se produit jamais


Le code ci-dessus démonte-t-il également l'historique.écoute? Cela ne se produit pas de mon côté.


Non, vous auriez besoin de renvoyer une fonction de démontage de l'effet



2
votes

Nous l'utilisons comme ceci:

const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
    history.listen(() => setIsOpen(false));
  }, [history]);


0 commentaires

0
votes

Si je comprends ce que vous demandez est ceci:

Vous souhaitez définir les indicateurs sur un tableau vide sans avoir à ajouter les valeurs précédentes en utilisant la méthode de diffusion que vous utilisez actuellement {... state, flags: []} . < / p>

Eh bien, ce n'est pas possible en utilisant useState et vous devez être prudent avec les objets d'état imbriqués car le clonage peut devenir coûteux avec des objets plus volumineux. C'est peut-être ce que vous essayez d'éviter ici .

Même si vous passez à useReducer , vous finirez toujours par diffuser des accessoires pour l'état.

Peut-être devriez-vous simplement avoir des indicateurs comme son propre état const [flags, setFlags] = useState ([]) ou regarder dans immutable-helper .

De plus, Essayez de respecter react-hooks / exhaust-deps d'autres femmes, des choses amusantes peuvent commencer à se produire. Si aucun deps, donnez au moins à votre hook un tableau vide pour vous assurer qu'il est exécuté une fois.


0 commentaires