En mi proyecto tengo algunos íconos de flecha (contenidos en el componente Skill ) y cuando haces clic en ellos, cambia su nombre de clase. Para verificar si se ha hecho clic en el componente, utilicé una matriz booleana como estado, por lo que cuando se activa el evento onClick, cambia el estado del componente. Los estados cambian correctamente, pero el componente no actualiza la clase y la representación se realiza (al igual que durante el montaje) solo después del primer clic.
El código de la página:
import { useState, useEffect } from 'react'; import Skill from '../../components/skill/skill.component'; import { skills } from './skills'; import './about-page.styles.scss'; const AboutPage = () => { console.log('render') const [cache, setCache] = useState([]); useEffect(() => { setCache(new Array(skills.length).fill(false)) }, []); const onToggleFunc = n => { cache[n] = !cache[n]; setCache(cache); console.log(cache); } return ( <div className='about-page'> <div className='container'> { skills.map((x, i) => ( <Skill isToggled={cache[i]} skillName={x.name} onClickFunc={() => (onToggleFunc(i))} key={i} /> )) } </div> </div> ) } export default AboutPage;el código del componente de habilidad:
import './skill.styles.scss'; import icon from '../../assets/icons/arrow.png'; const Skill = ({ isToggled, skillName, onClickFunc }) => ( <div className='skill-item'> <img src={icon} alt='icon' className={`icon ${isToggled ? 'toggled' : '' }`} onClick={onClickFunc} /> <span className='desc'>{skillName}</span> </div> ) export default Skill;Aquí la consola del navegador
Nunca debe mutar una variable de estado; en su lugar, debe crear una nueva referencia y actualizar la variable de estado llamando al método de actualización.
const AboutPage = () => { const [cache, setCache] = useState(() => new Array(skills.length).fill(false)); function onToggleFunc(n) { // create a new array from the previous one setCache(prevCache => prevCache.map((val, i) => i !== n ? val : !val)); } return ( <div className='about-page'> <div className='container'> { skills.map((x, i) => ( <Skill key={i} isToggled={cache[i]} skillName={x.name} onClickFunc={() => onToggleFunc(i)} /> )) } </div> </div> ) } export default AboutPage;