Skip to main content

Framework Integration

Hook-Fetch provides specialized integration support for mainstream frontend frameworks, allowing you to better use streaming data processing and request management features in React, Vue, and other frameworks.

React Integration​

Installation and Import​

import { useHookFetch } from 'hook-fetch/react';
import hookFetch from 'hook-fetch';

useHookFetch Hook​

useHookFetch is a Hook designed specifically for React, providing state management, error handling, and lifecycle management.

interface UseHookFetchOptions<Q> {
request: Q; // Request function
onError?: (error: Error) => void; // Error handling callback
}

Basic Usage​

import React from 'react';
import { useHookFetch } from 'hook-fetch/react';
import hookFetch from 'hook-fetch';

const api = hookFetch.create({
baseURL: 'https://api.example.com'
});

function UserProfile({ userId }: { userId: string }) {
const {
request,
loading,
cancel,
text,
stream
} = useHookFetch({
request: (id: string) => api.get(`/users/${id}`),
onError: (error) => console.error('Request failed:', error)
});

const [userData, setUserData] = React.useState(null);

const loadUser = async () => {
try {
const data = await request(userId).json();
setUserData(data);
} catch (error) {
console.error('Failed to load user:', error);
}
};

return (
<div>
<button onClick={loadUser} disabled={loading}>
{loading ? 'Loading...' : 'Load User'}
</button>
<button onClick={cancel}>Cancel</button>
{userData && <div>{JSON.stringify(userData)}</div>}
</div>
);
}

Streaming Chat Component​

import React, { useState, useEffect } from 'react';
import { useHookFetch } from 'hook-fetch/react';
import { sseTextDecoderPlugin } from 'hook-fetch/plugins/sse';

const chatApi = hookFetch.create({
baseURL: 'https://api.openai.com/v1',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
plugins: [
sseTextDecoderPlugin({
json: true,
prefix: 'data: ',
doneSymbol: '[DONE]'
})
]
});

function StreamingChat() {
const [messages, setMessages] = useState<string[]>([]);
const [currentMessage, setCurrentMessage] = useState('');
const [input, setInput] = useState('');

const { stream, loading, cancel } = useHookFetch({
request: (message: string) => chatApi.post('/chat/completions', {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: message }],
stream: true
}),
onError: (error) => {
console.error('Chat error:', error);
setCurrentMessage('Error: Failed to get response');
}
});

const sendMessage = async () => {
if (!input.trim() || loading) return;

const userMessage = input;
setInput('');
setMessages(prev => [...prev, `User: ${userMessage}`]);
setCurrentMessage('');

try {
for await (const chunk of stream(userMessage)) {
const delta = chunk.result?.choices?.[0]?.delta?.content;
if (delta) {
setCurrentMessage(prev => prev + delta);
}
}

// Add message to history when streaming is complete
setMessages(prev => [...prev, `AI: ${currentMessage}`]);
setCurrentMessage('');
} catch (error) {
console.error('Streaming error:', error);
}
};

return (
<div className="chat-container">
<div className="messages">
{messages.map((msg, index) => (
<div key={index} className="message">{msg}</div>
))}
{currentMessage && (
<div className="message streaming">
AI: {currentMessage}
<span className="cursor">|</span>
</div>
)}
</div>

<div className="input-area">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
placeholder="Type your message..."
disabled={loading}
/>
<button onClick={sendMessage} disabled={loading || !input.trim()}>
{loading ? 'Sending...' : 'Send'}
</button>
{loading && <button onClick={cancel}>Cancel</button>}
</div>
</div>
);
}

Vue Integration​

Installation and Import​

import { useHookFetch } from 'hook-fetch/vue';
import hookFetch from 'hook-fetch';

useHookFetch Composable​

useHookFetch is a composable function designed for Vue 3, providing reactive state management.

interface UseHookFetchOptions<Q> {
request: Q; // Request function
onError?: (error: Error) => void; // Error handling callback
}

Basic Usage​

<template>
<div>
<button @click="loadUser" :disabled="loading">
{{ loading ? 'Loading...' : 'Load User' }}
</button>
<button @click="cancel">Cancel</button>
<div v-if="userData">{{ userData }}</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useHookFetch } from 'hook-fetch/vue';
import hookFetch from 'hook-fetch';

const api = hookFetch.create({
baseURL: 'https://api.example.com'
});

const userData = ref(null);

const { request, loading, cancel } = useHookFetch({
request: (id: string) => api.get(`/users/${id}`),
onError: (error) => console.error('Request failed:', error)
});

const loadUser = async () => {
try {
const data = await request('123').json();
userData.value = data;
} catch (error) {
console.error('Failed to load user:', error);
}
};
</script>

Vue Streaming Chat Component​

<template>
<div class="chat-container">
<div class="messages">
<div v-for="(msg, index) in messages" :key="index" class="message">
{{ msg }}
</div>
<div v-if="currentMessage" class="message streaming">
AI: {{ currentMessage }}
<span class="cursor">|</span>
</div>
</div>

<div class="input-area">
<input
v-model="input"
@keyup.enter="sendMessage"
placeholder="Type your message..."
:disabled="loading"
/>
<button @click="sendMessage" :disabled="loading || !input.trim()">
{{ loading ? 'Sending...' : 'Send' }}
</button>
<button v-if="loading" @click="cancel">Cancel</button>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useHookFetch } from 'hook-fetch/vue';
import { sseTextDecoderPlugin } from 'hook-fetch/plugins/sse';

const chatApi = hookFetch.create({
baseURL: 'https://api.openai.com/v1',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
plugins: [
sseTextDecoderPlugin({
json: true,
prefix: 'data: ',
doneSymbol: '[DONE]'
})
]
});

const messages = ref<string[]>([]);
const currentMessage = ref('');
const input = ref('');

const { stream, loading, cancel } = useHookFetch({
request: (message: string) => chatApi.post('/chat/completions', {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: message }],
stream: true
}),
onError: (error) => {
console.error('Chat error:', error);
currentMessage.value = 'Error: Failed to get response';
}
});

const sendMessage = async () => {
if (!input.value.trim() || loading.value) return;

const userMessage = input.value;
input.value = '';
messages.value.push(`User: ${userMessage}`);
currentMessage.value = '';

try {
for await (const chunk of stream(userMessage)) {
const delta = chunk.result?.choices?.[0]?.delta?.content;
if (delta) {
currentMessage.value += delta;
}
}

// Add message to history when streaming is complete
messages.value.push(`AI: ${currentMessage.value}`);
currentMessage.value = '';
} catch (error) {
console.error('Streaming error:', error);
}
};
</script>

Best Practices​

1. Error Handling​

// React
const { request, loading } = useHookFetch({
request: (id: string) => api.get(`/users/${id}`),
onError: (error) => {
// Global error handling
if (error.response?.status === 401) {
// Handle unauthorized
redirectToLogin();
}
}
});

// Vue
const { request, loading } = useHookFetch({
request: (id: string) => api.get(`/users/${id}`),
onError: (error) => {
// Global error handling
if (error.response?.status === 401) {
// Handle unauthorized
await router.push('/login');
}
}
});

2. Loading States​

// React
function DataComponent() {
const { request, loading } = useHookFetch({
request: () => api.get('/data')
});

return (
<div>
{loading && <div>Loading...</div>}
{/* Component content */}
</div>
);
}

// Vue
<template>
<div>
<div v-if="loading">Loading...</div>
<!-- Component content -->
</div>
</template>

<script setup>
const { request, loading } = useHookFetch({
request: () => api.get('/data')
});
</script>

3. Request Cancellation​

// React
useEffect(() => {
return () => {
// Cancel request when component unmounts
cancel();
};
}, [cancel]);

// Vue
onUnmounted(() => {
// Cancel request when component unmounts
cancel();
});

The framework integration makes it easy to use Hook-Fetch's powerful features in modern frontend applications while maintaining clean, reactive code patterns.