Buen dia, Habr!Todos los desarrolladores de reactjs que se ocupan de la interactividad entre el frente y el frente se encuentran tarde o temprano, o se han encontrado o encontrarán el siguiente error:
Literalmente, resulta así:Advertencia. No se puede actualizar el estado Reaccionar para un componente desinstalado. Esta no es una operación, pero indica una pérdida de memoria en su aplicación. Para solucionarlo, cancele todas las suscripciones y tareas asincrónicas en la función de limpieza useEffect.
De hecho, todo es bastante simple, solo debes prestar atención a las siguientes frases:- No se puede realizar la actualización de estado
- un componente desinstalado;
- cancelar todas las suscripciones y tareas asincrónicas
- useEffect cleanup
En el corazón de los ganchos. ¡Entra bajo el corte!Entonces:- Todos los programadores de reactjs saben qué condición (estado) y que tal actualización (setState) también. No seré eso.
- . :
1) ;
2) ;
3) ;
— 3 . .
- . - , : . , async/await — .
- useEffect. return () => {} useEffect. , - , : .
Cometámonos un error: digamos que estamos desarrollando un sitio con una carga de descripción de película (no profundizaremos en la API moviedb , pero tomaremos una película específica como base). Tenemos dos paginas:Los enlaces a ambas páginas están disponibles en el panel de navegación, por ejemplo, en el encabezado. En la página principal ("Inicio") hay comunicación con la parte posterior para cargar información sobre la película./src/Pages/HomePage.jsimport React, { useState, useEffect } from 'react';
import { MOVIE_DB_GET } from '../config';
const HomePage = () => {
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(MOVIE_DB_GET);
const result = await response.json();
console.log(result, 'result')
} catch (e) {
console.error(e.message)
}
};
fetchData();
}, []);
return (
<main>
<h2> </h2>
</main>
)
};
export default HomePage;
/src/Pages/AboutPage.jsimport React from 'react';
const AboutPage = () => {
return (
<main>
<h2> </h2>
<p>
</p>
</main>
)
};
export default AboutPage;
Para mostrar información a través de una solicitud, es necesario escribir información en el estado para su posterior representación:/src/Pages/HomePage.jsimport React, { useState, useEffect } from 'react';
import { MOVIE_DB_GET } from '../config';
const HomePage = () => {
const [ movie, setMovie ] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(MOVIE_DB_GET);
const result = await response.json();
console.log(result, 'result');
setMovie(result);
} catch (e) {
console.error(e.message)
}
};
fetchData();
}, []);
return (
<main>
<h2> </h2>
<p> </p>
{
movie ? descriptionMovie() : false
}
</main>
)
};
export default HomePage;
Reproduciremos el error de la siguiente manera: cambiaremos de una ruta a otra, es decir, al estar en la página "Acerca de nosotros", iremos a la página "Inicio" e inmediatamente volveremos a la página "Acerca de nosotros" y listo " No se puede realizar ... .. " .El hecho es que el servidor no responde a las solicitudes al instante, se utiliza la asincronía para reproducir la solicitud en paralelo con las tareas necesarias. Pero en el caso de un retorno rápido a la página Acerca de nosotros, el componente Inicio se desmonta, lo que significa que el estado de este componente se restablecerá, pero la solicitud asincrónica seguirá iniciando setMovie, que ya no está allí y arrojará un error. La mejor solución es prohibir el uso de actualizaciones de estado al desmontar un componente:/src/Pages/HomePage.jsimport React, { useState, useEffect } from 'react';
import { MOVIE_DB_GET } from '../config';
const HomePage = () => {
const [ movie, setMovie ] = useState(null);
useEffect(() => {
let cleanupFunction = false;
const fetchData = async () => {
try {
const response = await fetch(MOVIE_DB_GET);
const result = await response.json();
console.log(result, 'result')
if(!cleanupFunction) setMovie(result);
} catch (e) {
console.error(e.message)
}
};
fetchData();
return () => cleanupFunction = true;
}, []);
return (
<main>
<h2> </h2>
<p> </p>
{
movie ? descriptionMovie() : false
}
</main>
)
};
export default HomePage;
Total:Todo el código fuente se puede ver aquí: https://gitlab.com/ImaGadzhiev/react-cant-perform