Estoy tratando de obtener una URL cuando la página se carga por primera vez y cuando cambia la ubicación. La primera carga funciona bien. La identificación del registro se extrae de los parámetros y, cuando eso cambia, se vuelve a llamar a useEffect para restablecer el estado y volver a cargar los nuevos registros. Sin embargo, todas las llamadas set* en useEffect no están haciendo nada ya que el método loadData() aún ve los datos antiguos (hasMoreData=false, dataRecords=[...]) .
export function MyComponent(props) { const [hasMoreData, setHasMoreData] = useState(true); const [dataRecords, setDataRecords] = useState([]); const [currentPage, setCurrentPage] = useState(1); const params = useParams(); const location = useLocation(); const { id } = params; const loadData = useCallback((page = 1) => { if (hasMoreData) { fetchSomeData(`api/records?id=${id}&page=${page}`).then((response) => { const { data } = response; // note: pagination logic omitted for clarity if (data && data.length > 0) { setDataRecords(data); } else { setHasMoreData(false); } }); } }, [id, dataRecords, hasMoreData]); useEffect(() => { // id param has changed, or its the first load - reset all fields, then fetch new data setHasMoreData(true); setDataRecords([]); setCurrentPage(1); loadData(currentPage); }, [location]); // ...currentPage managed via infiniteScroll };¿Qué estoy haciendo mal aquí?
Los comentarios sobre la pregunta original me llevan a una mejor manera de lograr lo que buscaba. Necesitaba detectar un cambio de ubicación, cambios de paginación y carga de datos en la carga de la página inicial y useCallback no era la mejor manera de hacerlo porque los cambios de estado son asíncronos y aún no veía los nuevos valores. En su lugar, usé un useEffect() separado para los cambios en la location para poder restablecer los datos de estado interno, y un segundo useEffect() para manejar los cambios en la currentPage en lugar de llamar a loadData() directamente.
export function MyComponent(props) { const [hasMoreData, setHasMoreData] = useState(true); const [dataRecords, setDataRecords] = useState([]); const [currentPage, setCurrentPage] = useState(1); const params = useParams(); const location = useLocation(); const { id } = params; useEffect(() => { // location changed, reset all data setHasMoreData(true); setDataRecords([]); setCurrentPage(1); }, [location]); useEffect(() => { // id param has changed, or its the first load - reset all fields, then fetch new data loadData(currentPage); function loadData(page = 1) { if (hasMoreData) { fetchSomeData(`api/records?id=${id}&page=${page}`).then((response) => { const { data } = response; // note: pagination logic omitted for clarity if (data && data.length > 0) { setDataRecords(data); } else { setHasMoreData(false); } }); } } }, [currentPage]); // ...currentPage managed via infiniteScroll };