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 { devlog } from "../utils";
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 cart = useCartStore(state => state.cart);
useEffect(() => {
useLayoutEffect(() => {
onTariffRemoveRef.current = onTariffRemove;
}, [onTariffRemove]);

@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useLayoutEffect, useRef } from "react";
import ReconnectingEventSource from "reconnecting-eventsource";
import { devlog } from "../utils";
@ -10,6 +10,14 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
onDisconnect: () => void;
marker?: string;
}) {
const onNewDataRef = useRef(onNewData);
const onDisconnectRef = useRef(onDisconnect);
useLayoutEffect(() => {
onNewDataRef.current = onNewData;
onDisconnectRef.current = onDisconnect;
}, [onNewData, onDisconnect]);
useEffect(() => {
if (!enabled) return;
@ -21,7 +29,7 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
try {
const newData = JSON.parse(event.data) as T;
devlog(`new SSE: ${marker}`, newData);
onNewData([newData]);
onNewDataRef.current([newData]);
} catch (error) {
devlog(`SSE parsing error: ${marker}`, event.data, error);
}
@ -32,7 +40,7 @@ export function useSSESubscription<T>({ enabled = true, url, onNewData, onDiscon
return () => {
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 { Tariff, GetTariffsResponse } from "../model/tariff";
import { devlog } from "../utils";
@ -12,6 +12,13 @@ export function useTariffs({ url, tariffsPerPage, apiPage, onNewTariffs, onError
onError: (error: Error) => void;
}) {
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() {
const controller = new AbortController();
@ -25,16 +32,16 @@ export function useTariffs({ url, tariffsPerPage, apiPage, onNewTariffs, onError
}).then((result) => {
devlog("GetTariffsResponse", result);
if (result.tariffs.length > 0) {
onNewTariffs(result.tariffs);
onNewTariffsRef.current(result.tariffs);
setFetchState("idle");
} else setFetchState("all fetched");
}).catch(error => {
devlog("Error fetching tariffs", error);
onError(error);
onErrorRef.current(error);
});
return () => controller.abort();
}, [onError, onNewTariffs, apiPage, tariffsPerPage, url]);
}, [apiPage, tariffsPerPage, url]);
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 { devlog } from "../utils";
import { makeRequest } from "../api";
@ -14,6 +14,13 @@ export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticket
isUnauth?: boolean;
}) {
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() {
if (!ticketId) return;
@ -35,16 +42,16 @@ export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticket
}).then(result => {
devlog("GetMessagesResponse", result);
if (result?.length > 0) {
onNewMessages(result);
onNewMessagesRef.current(result);
setFetchState("idle");
} else setFetchState("all fetched");
}).catch(error => {
devlog("Error fetching messages", error);
onError(error);
onErrorRef.current(error);
});
return () => controller.abort();
}, [isUnauth, makeRequest, messageApiPage, messagesPerPage, onError, onNewMessages, ticketId, url]);
}, [isUnauth, messageApiPage, messagesPerPage, ticketId, url]);
return fetchState;
}

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