Maison > Questions et réponses > le corps du texte
P粉4410764052023-08-31 15:23:23
Vous pouvez utiliser Redux
.
openAllAccordions
, parcourez les identifiants et définissez l'accordéon appartenant à cet identifiant sur open=truecloseAllAccordions
, parcourez les identifiants et définissez l'accordéon appartenant à cet identifiant sur open=falseP粉8091101292023-08-31 12:37:09
Dans une collection plus ou moins arbitraire d'instances de composants, il est courant d'avoir besoin d'une certaine coordination. Une approche que j'ai utilisée avec succès consiste à créer un Context avec un hook associé avec lequel les composants peuvent être enregistrés. Ce hook renvoie une vue de l'état partagé et une fonction qui modifie cet état en fonction de vos besoins.
Ici, vous pouvez créer un contexte qui stocke les opener
函数并提供openAll
/closeAll
fonctions pour chaque composant enregistré :
const AccordionProvider = ({ children }) => { const [openers] = useState(new Set()); // 当创建时,是否应该展开新的可折叠项? //(支持递归展开是必要的) const [defaultOpen, setDefaultOpen] = useState(false); const register = useCallback( (opener) => { openers.add(opener); return () => openers.delete(opener); // 返回一个用于`useEffect`的取消注册函数 }, [openers] ); const openAll = useCallback(() => { setDefaultOpen(true); openers.forEach(opener => opener(true)), }, [setDefaultOpen, openers]); const closeAll = useCallback(() => { setDefaultOpen(false); openers.forEach(opener => opener(false)), }, [setDefaultOpen, openers]); return ( <AccordionContext.Provider value={{ register, openAll, closeAll, defaultOpen }} children={children} /> ); };
...Il existe également un hook appelé par chaque composant enfant pour s'enregistrer dans le contexte et renvoyer la valeur toggle
/open
familière :
const useAccordionAsClient = () => { const { register, defaultOpen } = useContext(AccordionContext); const [open, opener] = useState(defaultOpen); const toggle = useCallback(() => opener((open) => !open), [opener]); useEffect(() => register(opener), [register, opener]); return { toggle, open }; };
Il existe également un hook séparé pour effectuer des opérations par lots, ce qui est également pratique :
const useAccordionAsManager = () => { const { openAll, closeAll } = useContext(AccordionContext); return { openAll, closeAll }; };
Veuillez noter que par souci de simplicité, une fonction opener
(又名setOpen
) distincte est utilisée ici comme identifiant unique pour chaque composant enregistré. Une alternative flexible consiste à utiliser d'autres identifiants afin de pouvoir ouvrir/fermer des accordéons arbitraires dans la navigation, etc.