Bom dia, Habr!Todos os desenvolvedores do reactjs que lidam com interatividade entre a parte traseira e a frente se encontram mais cedo ou mais tarde, ou se encontraram ou encontrarão o seguinte erro:
Literalmente, acontece assim:Atenção. Não foi possível atualizar o estado React para um componente desinstalado. Isso não é uma operação, mas indica um vazamento de memória no seu aplicativo. Para corrigir, cancele todas as assinaturas e tarefas assíncronas na função de limpeza useEffect.
De fato, tudo é bem simples, basta prestar atenção às seguintes frases:- Não foi possível executar a atualização do estado
- um componente desinstalado;
- cancelar todas as assinaturas e tarefas assíncronas
- limpeza useEffect
No coração dos ganchos. Vá sob o corte!Assim:- Todos os programadores do reactjs sabem que condição (estado) e que tal atualização (setState) também. Eu não serei isso.
- . :
1) ;
2) ;
3) ;
— 3 . .
- . - , : . , async/await — .
- useEffect. return () => {} useEffect. , - , : .
Vamos cometer um erro: digamos que estamos desenvolvendo um site com as descrições de filmes carregadas (não vamos aprofundar na API do moviedb , mas usar um filme específico como base). Temos duas páginas:Os links para as duas páginas estão disponíveis no painel de navegação, por exemplo, no cabeçalho. Na página principal ("Página inicial"), há uma comunicação com a parte traseira para enviar informações sobre o filme./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 exibir informações por meio de uma solicitação, é necessário gravar informações no estado para renderização subsequente:/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;
Reproduziremos o erro da seguinte maneira - alternaremos de uma rota para outra, ou seja, estando na página “Sobre nós”, iremos para a página “Página inicial” e imediatamente retornaremos novamente à página “Sobre nós” e voila “ Não é possível executar ... .. ” .O fato é que o servidor não responde às solicitações instantaneamente; a assincronia é usada para ainda executar a solicitação paralelamente às tarefas necessárias. Mas, no caso de um retorno rápido à página Sobre nós, o componente Início é desmontado, o que significa que o estado desse componente será redefinido, mas a solicitação assíncrona ainda ativará o setMovie, que não está mais lá e gerará um erro. A melhor solução é proibir o uso de atualizações de estado ao desmontar um 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 o código fonte pode ser visto aqui: https://gitlab.com/ImaGadzhiev/react-cant-perform