Реакция: как получить исходный API и дополнительные подписки в одном и том же хуке?
Я пытаюсь создать приложение чата, используя urql в качестве клиента graphql.
- Первоначально все текущие сообщения извлекались с помощью одного запроса graphql. Это делается в
useFetchInitialMessages
крючок. - Все инкрементальные сообщения добавляются к состоянию сообщений с помощью запроса подписки. Это делается в
useSubscribeMessages
крючок.
Есть ли способ объединить их в один хук, который будет обрабатывать загрузку начального сообщения, а также последующие обновления из-за подписки?
Хук для получения исходных данных
function useFetchInitialMessages(channelId) {
const query = `
query GetMessages($channelId) {
message(where: {channelId: {_eq: $channelId}}) {
id,
content
}
}
`;
const [{ fetching, error, data }] = urql.useQuery({
query,
variables: { channelId: channelId },
});
return { fetching, error, data };
}
Крючок для подписки на новые сообщения
function useSubscribeMessages(channelId, initialMessages) {
const query = `subscription NewMessageSubscription($channelId: String!) {
message(channelId: $channelId) {
id,
content
}
}
`;
const handleNewMessage = (messages = initialMessages, response) => {
return [response.message, ...messages];
};
const [res] = useSubscription(
{ query: query, variables: { channelId: channelId } },
handleSubscription
);
return [res];
}
Составная часть
function MessageList(props: Props) {
const { channel } = props;
const { fetching, error, data: initialMessages } = useFetchInitialMessages(
channel.id
);
const [res] = useSubscribeMessages(channel.id, initialMessages);
if (fetching) {
return <p>"Loading..."</p>;
}
if (!res.data) {
return (
<ul>
{initialMessages.map((message) => {
<li>message.content</li>;
})}
</ul>
);
}
return (
<ul>
{res.data.map((message) => {
<li>message.content</li>;
})}
</ul>
);
}