refactor hooks

This commit is contained in:
nflnkr 2023-07-10 20:48:09 +03:00
parent b0f2e94ebf
commit 4956543b7e
5 changed files with 47 additions and 18 deletions

@ -1,4 +1,4 @@
import { useEffect, useRef } from "react"; import { useEffect, useLayoutEffect, useRef } from "react";
import { isAxiosError } from "axios"; import { isAxiosError } from "axios";
import { devlog } from "../utils"; import { devlog } from "../utils";
import { addCartTariffs, removeMissingCartTariffs, setCartTariffStatus, useCartStore } from "../stores/cart"; import { addCartTariffs, removeMissingCartTariffs, setCartTariffStatus, useCartStore } from "../stores/cart";
@ -15,7 +15,7 @@ export function useCart({ tariffs, tariffIds, onTariffRemove }: {
const cartTariffMap = useCartStore(state => state.cartTariffMap); const cartTariffMap = useCartStore(state => state.cartTariffMap);
const cart = useCartStore(state => state.cart); const cart = useCartStore(state => state.cart);
useEffect(() => { useLayoutEffect(() => {
onTariffRemoveRef.current = onTariffRemove; onTariffRemoveRef.current = onTariffRemove;
}, [onTariffRemove]); }, [onTariffRemove]);

@ -1,4 +1,4 @@
import { useEffect } from "react"; import { useEffect, useLayoutEffect, useRef } from "react";
import ReconnectingEventSource from "reconnecting-eventsource"; import ReconnectingEventSource from "reconnecting-eventsource";
import { devlog } from "../utils"; import { devlog } from "../utils";
@ -10,6 +10,14 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
onDisconnect: () => void; onDisconnect: () => void;
marker?: string; marker?: string;
}) { }) {
const onNewDataRef = useRef(onNewData);
const onDisconnectRef = useRef(onDisconnect);
useLayoutEffect(() => {
onNewDataRef.current = onNewData;
onDisconnectRef.current = onDisconnect;
}, [onNewData, onDisconnect]);
useEffect(() => { useEffect(() => {
if (!enabled) return; if (!enabled) return;
@ -21,7 +29,7 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
try { try {
const newData = JSON.parse(event.data) as T; const newData = JSON.parse(event.data) as T;
devlog(`new SSE: ${marker}`, newData); devlog(`new SSE: ${marker}`, newData);
onNewData([newData]); onNewDataRef.current([newData]);
} catch (error) { } catch (error) {
devlog(`SSE parsing error: ${marker}`, event.data, error); devlog(`SSE parsing error: ${marker}`, event.data, error);
} }
@ -32,7 +40,7 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
return () => { return () => {
eventSource.close(); eventSource.close();
onDisconnect(); onDisconnectRef.current();
}; };
}, [enabled, marker, onDisconnect, onNewData, url]); }, [enabled, marker, url]);
} }

@ -1,4 +1,4 @@
import { useEffect, useState } from "react"; import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { makeRequest } from "../api"; import { makeRequest } from "../api";
import { Tariff, GetTariffsResponse } from "../model/tariff"; import { Tariff, GetTariffsResponse } from "../model/tariff";
import { devlog } from "../utils"; import { devlog } from "../utils";
@ -12,6 +12,13 @@ export function useTariffs({ url, tariffsPerPage, apiPage, onNewTariffs, onError
onError: (error: Error) => void; onError: (error: Error) => void;
}) { }) {
const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle"); const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle");
const onNewTariffsRef = useRef(onNewTariffs);
const onErrorRef = useRef(onError);
useLayoutEffect(() => {
onNewTariffsRef.current = onNewTariffs;
onErrorRef.current = onError;
}, [onNewTariffs, onError]);
useEffect(function fetchTickets() { useEffect(function fetchTickets() {
const controller = new AbortController(); const controller = new AbortController();
@ -25,16 +32,16 @@ export function useTariffs({ url, tariffsPerPage, apiPage, onNewTariffs, onError
}).then((result) => { }).then((result) => {
devlog("GetTariffsResponse", result); devlog("GetTariffsResponse", result);
if (result.tariffs.length > 0) { if (result.tariffs.length > 0) {
onNewTariffs(result.tariffs); onNewTariffsRef.current(result.tariffs);
setFetchState("idle"); setFetchState("idle");
} else setFetchState("all fetched"); } else setFetchState("all fetched");
}).catch(error => { }).catch(error => {
devlog("Error fetching tariffs", error); devlog("Error fetching tariffs", error);
onError(error); onErrorRef.current(error);
}); });
return () => controller.abort(); return () => controller.abort();
}, [onError, onNewTariffs, apiPage, tariffsPerPage, url]); }, [apiPage, tariffsPerPage, url]);
return fetchState; return fetchState;
} }

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState, useEffect, useRef, useLayoutEffect } from "react";
import { TicketMessage, GetMessagesRequest, GetMessagesResponse } from "../model"; import { TicketMessage, GetMessagesRequest, GetMessagesResponse } from "../model";
import { devlog } from "../utils"; import { devlog } from "../utils";
import { makeRequest } from "../api"; import { makeRequest } from "../api";
@ -14,6 +14,13 @@ export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticket
isUnauth?: boolean; isUnauth?: boolean;
}) { }) {
const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle"); const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle");
const onNewMessagesRef = useRef(onNewMessages);
const onErrorRef = useRef(onError);
useLayoutEffect(() => {
onNewMessagesRef.current = onNewMessages;
onErrorRef.current = onError;
}, [onNewMessages, onError]);
useEffect(function fetchTicketMessages() { useEffect(function fetchTicketMessages() {
if (!ticketId) return; if (!ticketId) return;
@ -35,16 +42,16 @@ export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticket
}).then(result => { }).then(result => {
devlog("GetMessagesResponse", result); devlog("GetMessagesResponse", result);
if (result?.length > 0) { if (result?.length > 0) {
onNewMessages(result); onNewMessagesRef.current(result);
setFetchState("idle"); setFetchState("idle");
} else setFetchState("all fetched"); } else setFetchState("all fetched");
}).catch(error => { }).catch(error => {
devlog("Error fetching messages", error); devlog("Error fetching messages", error);
onError(error); onErrorRef.current(error);
}); });
return () => controller.abort(); return () => controller.abort();
}, [isUnauth, makeRequest, messageApiPage, messagesPerPage, onError, onNewMessages, ticketId, url]); }, [isUnauth, messageApiPage, messagesPerPage, ticketId, url]);
return fetchState; return fetchState;
} }

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState, useEffect, useRef, useLayoutEffect } from "react";
import { GetTicketsResponse, GetTicketsRequest } from "../model"; import { GetTicketsResponse, GetTicketsRequest } from "../model";
import { devlog } from "../utils"; import { devlog } from "../utils";
import { makeRequest } from "../api"; import { makeRequest } from "../api";
@ -12,6 +12,13 @@ export function useTickets({ url, ticketsPerPage, ticketApiPage, onNewTickets, o
onError: (error: Error) => void; onError: (error: Error) => void;
}) { }) {
const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle"); const [fetchState, setFetchState] = useState<"fetching" | "idle" | "all fetched">("idle");
const onNewTicketsRef = useRef(onNewTickets);
const onErrorRef = useRef(onError);
useLayoutEffect(() => {
onNewTicketsRef.current = onNewTickets;
onErrorRef.current = onError;
}, [onNewTickets, onError]);
useEffect(function fetchTickets() { useEffect(function fetchTickets() {
const controller = new AbortController(); const controller = new AbortController();
@ -30,16 +37,16 @@ export function useTickets({ url, ticketsPerPage, ticketApiPage, onNewTickets, o
}).then((result) => { }).then((result) => {
devlog("GetTicketsResponse", result); devlog("GetTicketsResponse", result);
if (result.data) { if (result.data) {
onNewTickets(result); onNewTicketsRef.current(result);
setFetchState("idle"); setFetchState("idle");
} else setFetchState("all fetched"); } else setFetchState("all fetched");
}).catch(error => { }).catch(error => {
devlog("Error fetching tickets", error); devlog("Error fetching tickets", error);
onError(error); onErrorRef.current(error);
}); });
return () => controller.abort(); return () => controller.abort();
}, [makeRequest, onError, onNewTickets, ticketApiPage, ticketsPerPage, url]); }, [ticketApiPage, ticketsPerPage, url]);
return fetchState; return fetchState;
} }