Dentro de mi aplicación, uno de mis componentes, lamentablemente, envía la advertencia No se puede realizar una actualización de estado de reacción en un componente desmontado. Me está volviendo loco en este momento. Estaba tratando de ubicar el lugar exacto donde podría estar sucediendo, pero desafortunadamente no tuve éxito.
¿Alguna idea de qué podría estar causando o cómo encontrar el origen del problema? Agradecería cualquier ayuda o dirección donde mirar.
La consola:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. CurrencySelect@http://localhost:3000/static/js/main.chunk.js:4444:24 CurrencySelect Controller@http://localhost:3000/static/js/vendors~main.chunk.js:118828:29 CurrencySelect@http://localhost:3000/static/js/main.chunk.js:10270:26Componente:
import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import CountrySelectOption from '../CountrySelectOption/CountrySelectOption'; import CountrySelectValue from '../CountrySelectValue/CountrySelectValue'; import Select from '../../../custom/ChakraReactSelect/ChakraReactSelect'; import { getCurrencies, getCurrenciesOptionsData } from '../../../../services/currencies/currenciesServices'; const currencySelectComponent = { Option: CountrySelectOption, SingleValue: CountrySelectValue }; function CurrencySelect({ size = 'lg', isSearchable = true, ...other }) { const [currenciesOptions, setCurrenciesOptions] = useState([]); const [isLoading, setIsLoading] = useState(false); useEffect(() => { let isMounted = true; const prepareCurrenciesOptions = async () => { try { if (isMounted) { setIsLoading(true); const currencies = await (await getCurrencies()).json(); const preparedData = getCurrenciesOptionsData(currencies); setCurrenciesOptions(preparedData); setIsLoading(false); } } catch (err) { console.error(err); } }; prepareCurrenciesOptions(); return () => { isMounted = false; }; }, []); return ( <Select {...other} size={size} isSearchable={isSearchable} isClearable placeholder={isLoading ? 'Loading currencies...' : 'Select currency...'} options={currenciesOptions} components={currencySelectComponent} isLoading={isLoading} isDisabled={isLoading} openMenuOnFocus={true} /> ); } const CurrencySelectRef = React.forwardRef((props, _) => ( <CurrencySelect {...props} /> )); CurrencySelectRef.displayName = 'CurrencySelect'; export default CurrencySelectRef; CurrencySelect.propTypes = { size: PropTypes.string, isSearchable: PropTypes.bool, ref: PropTypes.func };La respuesta fue bajar la verificación isMounted después de esperar a getCurrencies(), así:
código antiguo:
useEffect(() => { let isMounted = true; const prepareCurrenciesOptions = async () => { try { if (isMounted) { setIsLoading(true); const currencies = await (await getCurrencies()).json(); const preparedData = getCurrenciesOptionsData(currencies); setCurrenciesOptions(preparedData); setIsLoading(false); } } catch (err) { console.error(err); } }; prepareCurrenciesOptions(); return () => { isMounted = false; }; }, []);nuevo código:
useEffect(() => { let isMounted = true; const prepareCurrenciesOptions = async () => { try { setIsLoading(true); const currencies = await (await getCurrencies()).json(); // Currncies might still be pending when te component is already unmounted // This is to prevent the state updating on already unmounted component if (isMounted) { const preparedData = getCurrenciesOptionsData(currencies); setCurrenciesOptions(preparedData); setIsLoading(false); } } catch (err) { console.error(err); } }; prepareCurrenciesOptions(); return () => { isMounted = false; }; }, []);