T
TanStack10mo ago
exotic-emerald

What is the right way to do on click SSE query that feeds multiple components

I have a long running Server-Sent-Event query that I want to fire on button click and the events from it are rendered in two components on the same page. The query should be cancellable as well. This is the rough pseudo-example with questions:
// APIClinet.ts
// I would like this to be reusable, if possible
export const sseQuery = (id: string, filter: string, onMessage: (msg: SSEMessage) => void) => {
// I could use useQuery with skipToken, but then I have to make id and filter as (string | undefined)?
// I don't really like this, as both are required for the query

// alternatively, useMutation, but then I have to pass my own AbortController/Signal and handle everything around it?

// is there another way I am not seeing?
}

// Page.tsx
const MyPage = (): JSX.Element => {
const [id, setID] = useState<string>()
const [filter, setFilter] = useState<string>()
const [data, setData] = useState<Array<SSEMessage>>([])
const onMessage = (msg: SSEMessage) => setData([...data, msg])
// how do I handle that id and filter is not set initially?
// There are no default values that would work
const query = APIClient.sseQuery(...)

return (
<>
<IDSelector onSelect={setID} />
<Button onClick={setFilterValueAndFireOffTheQuerySomehow()} />
<Button onClick={queryClient.cancelQuery(...)} />
{(query.isFetching || query.isSuccess) && <ComponentA data={data} />}
{(query.isFetching || query.isSuccess) && <ComponentB data={data} />}
</>
)
}
// APIClinet.ts
// I would like this to be reusable, if possible
export const sseQuery = (id: string, filter: string, onMessage: (msg: SSEMessage) => void) => {
// I could use useQuery with skipToken, but then I have to make id and filter as (string | undefined)?
// I don't really like this, as both are required for the query

// alternatively, useMutation, but then I have to pass my own AbortController/Signal and handle everything around it?

// is there another way I am not seeing?
}

// Page.tsx
const MyPage = (): JSX.Element => {
const [id, setID] = useState<string>()
const [filter, setFilter] = useState<string>()
const [data, setData] = useState<Array<SSEMessage>>([])
const onMessage = (msg: SSEMessage) => setData([...data, msg])
// how do I handle that id and filter is not set initially?
// There are no default values that would work
const query = APIClient.sseQuery(...)

return (
<>
<IDSelector onSelect={setID} />
<Button onClick={setFilterValueAndFireOffTheQuerySomehow()} />
<Button onClick={queryClient.cancelQuery(...)} />
{(query.isFetching || query.isSuccess) && <ComponentA data={data} />}
{(query.isFetching || query.isSuccess) && <ComponentB data={data} />}
</>
)
}
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?