Estoy tratando de ocultar varios divs con useSate.
Se representarán aleatoriamente en la página, no de una lista.
Logré hacerlo configurando diferentes variables pero no pude encontrar una solución más genérica: https://stackblitz.com/edit/react-t3shrc?file=src%2FApp.js
¿También hay alguna manera de cerrarlos al hacer clic afuera?
Podrías ayudarme por favor.
export default function App() { const [isVisible, setIsVisible] = useState(false); const [isVisible2, setIsVisible2] = useState(false); const showInfo = (e, setIsVisible) => { e.preventDefault(); setIsVisible(true); }; const hideInfo = (e, setIsVisible) => { e.preventDefault(); setIsVisible(false); }; return ( <div> <button onClick={(e) => { showInfo(e, setIsVisible); }} > Show info 1 </button> {isVisible && ( <div className="info"> Info 1 <button onClick={(e) => { hideInfo(e, setIsVisible); }} > Close </button> </div> )} <br></br> <br></br> <button onClick={(e) => { showInfo(e, setIsVisible2); }} > Show info 2 </button> {isVisible2 && ( <div className="info"> Info 2 <button onClick={(e) => { hideInfo(e, setIsVisible2); }} > Close </button> </div> )} </div> ); }No estoy 100% seguro de lo que quiere decir con una solución más 'genérica'. Esto es lo que me viene a la mente:
En primer lugar, creamos un objeto más complejo para contener básicamente todas las variables/secciones que encontramos y lo usamos como nuestro estado.
const initialVisibleAreas = { area1: true, area2: false }; const [visibleAreas, setVisibleAreas] = useState(initialVisibleAreas);Tenga en cuenta que esto es probablemente algo que desea generar a partir de sus datos utilizando Object.keys (...) o mapeando una matriz.
A continuación, creamos las funciones para que los botones usen este nuevo estado en consecuencia:
// shows the element by given key const showInfo = (event, key) => { event.preventDefault(); setVisibleAreas({ ...visibleAreas, ...{ [key]: true } }); }; // hides the element by given key const hideInfo = (event, key) => { event.preventDefault(); setVisibleAreas({ ...visibleAreas, ...{ [key]: false } }); }; // sets every key to false to hide them all at once const hideAllInfo = (event) => { event.preventDefault(); const allFalse = Object.assign( ...Object.keys(visibleAreas).map((key) => ({ [key]: false })) ); setVisibleAreas(allFalse); };Por último, pero no menos importante, los usamos en jsx. Esta es básicamente una 'sección':
<button onClick={(e) => { showInfo(e, 'area2'); }} > Show info 2 </button> { visibleAreas['area2'] && ( <div className="info"> Info 2 <button onClick={(e) => { hideInfo(e, 'area2'); }} > Close </button> </div> ); }Para responder a la última pregunta; nada le impide llamar a 'hideAllInfo' dentro de un controlador onClick de su div circundante. La muestra está incluida en el stackblitz modificado.
Eche un vistazo completo al stackblitz modificado
EDITAR: en el caso de que desee cerrar todas las áreas haciendo clic en el div circundante, asegúrese de no propagar el evento de clic de botón con:
event.stopPropagation();Actualicé el stackblitz una vez más.