Skip to content

Commit

Permalink
feat(next/web): new hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
sdjdd committed Mar 14, 2024
1 parent cbf6618 commit 6bfc276
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 21 deletions.
6 changes: 3 additions & 3 deletions next/web/src/App/Admin/Tickets/Ticket/mixed-ticket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { LCObject } from 'open-leancloud-storage/core';

import { db } from '@/leancloud';
import { TicketDetailSchema, UpdateTicketData, useTicket, useUpdateTicket } from '@/api/ticket';
import { useCurrentRef } from '@/utils/useCurrentRef';
import { Ticket_v1, UpdateTicket_v1Data, useTicket_v1, useUpdateTicket_v1 } from './api1';
import { useEffectEvent } from '@/utils/useEffectEvent';

interface MixedTicket {
id: TicketDetailSchema['id'];
Expand Down Expand Up @@ -129,7 +129,7 @@ export function useMixedTicket(ticketId: string): UseMixedTicketResult {
}
};

const onUpdate = useCurrentRef((ticketObj: LCObject) => {
const onUpdate = useEffectEvent((ticketObj: LCObject) => {
if (!ticket) {
return;
}
Expand All @@ -147,7 +147,7 @@ export function useMixedTicket(ticketId: string): UseMixedTicketResult {
const subscription = db.query('Ticket').where('objectId', '==', ticket.id).subscribe();
subscription.then((s) => {
if (mounted) {
s.on('update', (o) => onUpdate.current(o));
s.on('update', onUpdate);
}
});

Expand Down
19 changes: 8 additions & 11 deletions next/web/src/App/Admin/Tickets/Ticket/timeline-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { last } from 'lodash-es';
import { db } from '@/leancloud';
import { ReplySchema } from '@/api/reply';
import { fetchTicketReplies, fetchTicketOpsLogs, OpsLog } from '@/api/ticket';
import { useCurrentRef } from '@/utils/useCurrentRef';
import { useEffectEvent } from '@/utils/useEffectEvent';
import { useFreshState } from '@/utils/useFreshState';

interface Reader<T> {
read: () => Promise<T | undefined>;
Expand Down Expand Up @@ -165,7 +165,7 @@ const reverseDataPageSize = 50;
export function useTimeline(ticketId?: string) {
const [timelineReader, setTimelineReader] = useState<Reader<TimelineData>>();

const ticketIdRef = useCurrentRef(ticketId);
const isFresh = useFreshState([ticketId]);
const isMounted = useMountedState();

const [data, setData] = useState<TimelineData[]>();
Expand All @@ -177,7 +177,6 @@ export function useTimeline(ticketId?: string) {
const [isLoadingMore, setIsLoadingMore] = useState(false);

const refetch = useEffectEvent(async () => {
const ticketId = ticketIdRef.current;
if (!ticketId) return;

const timelineReader = createTimelineReader({
Expand All @@ -199,13 +198,13 @@ export function useTimeline(ticketId?: string) {
data.length === dataPageSize
? await take(reverseTimelineReader, reverseDataPageSize)
: undefined;
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setMoreData(undefined);
setData(data);
setReverseData(reverseData);
}
} finally {
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setIsLoading(false);
}
}
Expand All @@ -220,15 +219,14 @@ export function useTimeline(ticketId?: string) {
if (!data?.length || !reverseData?.length) return;
if (last(data)!.ts >= last(reverseData)!.ts) return;
if (!timelineReader) return;
const ticketId = ticketIdRef.current;
try {
setIsLoadingGap(true);
const newData = await take(timelineReader, dataPageSize);
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setData((data) => [...(data || []), ...newData]);
}
} finally {
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setIsLoadingGap(false);
}
}
Expand All @@ -241,18 +239,17 @@ export function useTimeline(ticketId?: string) {
refetch();
return;
}
const ticketId = ticketIdRef.current;
if (!ticketId) return;
try {
setIsLoadingMore(true);
const cursor = lastItem.data.createdAt;
const reader = createTimelineReader({ ticketId, cursor, pageSize: 10 });
const data = await take(reader, 10);
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setMoreData((prev) => [...(prev || []), ...data]);
}
} finally {
if (ticketId === ticketIdRef.current && isMounted()) {
if (isMounted() && isFresh()) {
setIsLoadingMore(false);
}
}
Expand Down
7 changes: 0 additions & 7 deletions next/web/src/utils/useCurrentRef.ts

This file was deleted.

13 changes: 13 additions & 0 deletions next/web/src/utils/useFreshState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DependencyList } from 'react';
import { useLatest } from 'react-use';
import { isEqual } from 'lodash-es';

import { useEffectEvent } from './useEffectEvent';

/**
* Check all states is fresh in async function or callback
*/
export function useFreshState(deps: DependencyList) {
const latestDeps = useLatest(deps);
return useEffectEvent(() => isEqual(deps, latestDeps.current));
}

0 comments on commit 6bfc276

Please sign in to comment.