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
GlobalProvider
pourrait être démonté entre les changements dechemin
avec son état par défaut.