Estoy tratando de hacer un pequeño menú desplegable de texto. Cuando haga clic en el texto del encabezado, se mostrará la etiqueta p. Está funcionando, pero... está alternando todos ellos, cuando solo hago clic en ellos. Tengo varias etiquetas "li" con texto y la función. Así que no estoy bucleando nada
const [isActive, setActive] = useState(false) const toggleText = () => { setActive(!isActive) } <li> <h2 onClick={toggleText}>Lorem ipsum dolar sit amet</h2> {isActive && ( <p> Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ut reprehenderit explicabo laudantium quas, minus recusandae quibusdam dolorem dolorum possimus natus quod nam, et labore iste eos? Ducimus optio dolor soluta! </p> )} <div onClick={toggleText} className='dropDown__plus'> {!isActive ? ( <img src={plusIcon} alt='Plus icon' /> ) : ( <img src={minusIcon} alt='Minus Icon' /> )} </div> </li>Según su pregunta y los comentarios, está reutilizando el estado isActive en varios elementos del mismo componente, lo que significa que cada elemento no tiene su propio estado isActive : todos comparten el mismo estado globalmente.
Puede crear un componente secundario que maneje el estado exclusivamente, mientras le permite recibir contenidos en forma de props , por ejemplo, para el encabezado y el contenido:
import { useState } from "react"; export default function MyComponent(props) { const [isActive, setActive] = useState(false); const toggleText = () => { setActive(!isActive); }; return ( <li> <h2 onClick={toggleText}>{props.heading}</h2> {isActive && props.content} <button type="button" onClick={toggleText} className="dropDown__plus"> {!isActive ? <>+</> : <>-</>} </button> </li> ); } Luego, en su componente principal original, solo es cuestión de usar <MyComponent> para manejar todas sus entradas <li> :
<ul> <MyComponent heading="Lorem ipsum dolor sit amet" content={<p>Some text here</p>} /> <MyComponent heading="Foo bar" content={<p>More foo bar content</p>} /> <MyComponent heading="Last header" content={<p>C'est la vie</p>} /> </ul>Puedes ver un ejemplo de prueba de concepto aquí: