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 état actuel pour les autres articles?
3 Réponses :
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)
}, []);
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
Nous l'utilisons comme ceci:
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
history.listen(() => setIsOpen(false));
}, [history]);
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.
pouvez-vous fournir un code et une boîte?
Il semble que votre
GlobalProviderpourrait être démonté entre les changements decheminavec son état par défaut.