Estoy tratando de actualizar el estado en un componente de orden superior de un niño. Mi solución es establecer el estado en verdadero después de configurar las etiquetas. useEffect se ejecuta cuando el estado es verdadero, primero actualiza el estado en el componente principal y luego actualiza el estado a falso, lo que detiene su invocación. Mi solución antes mencionada es la única forma en que he logrado evitar el bucle infinito de useEffect.
const Student = ({ appendTags, student: { id: studentId, firstName, lastName, pic, email, company, skill, grades, tags: studentTags }}) => { const fullName = `${firstName} ${lastName}`; const [tag, setTag] = useState(''); const [tags, setTags] = useState([]); const [stateUpdated, setStateUpdated] = useState(false); const [displayGrades, setDisplayGrades] = useState(false); const onTagsSubmit = e => { if (tag.length) { e.preventDefault(); setTags(prevState => [...prevState, tag]); setStateUpdated(true); setTag(''); } } useEffect(() => { if (stateUpdated) { appendTags(studentId, tags); setStateUpdated(false); }; }, [stateUpdated, setStateUpdated, tags, appendTags, studentId]);Parece que esto es lo que tenemos, si eliminas stateUpdated .
Supongo que en la llamada appendTags() , el componente principal cambia su estado y se vuelve a procesar. Después de eso, se vuelve a crear la función appendTags . El componente secundario Student también se recrea. El useEffect del estudiante ve que una de las dependencias, appendTags , ha cambiado, por lo que debe volver a ejecutarse. Llama a appendTags() y tenemos un ciclo.
Para solucionarlo, debe envolver appendTags en useCallback hook dentro del componente principal :
const appendTags = useCallback((id, tags) => { // update local state }, []); // ... return <Student appendTags={appendTags} /* (...) */ />