반응형
AIKit — React & Vue 연동
자주 받는 질문
"React에서 어떻게 쓰나요?" — AIKit은 순수 JavaScript 라이브러리다. 모든 프레임워크에서 동일하게 동작한다. 핵심은 프레임워크의 상태 관리 패턴에 맞춰 감싸는 것이다.
React 연동
Custom Hook
// useAIKit.js
import { useState, useRef, useCallback } from 'react';
export function useAIKit(config) {
const aiRef = useRef(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [messages, setMessages] = useState([]);
// 초기화 (한 번만)
if (!aiRef.current) {
aiRef.current = new AIKit(config);
}
const sendMessage = useCallback(async (message) => {
setLoading(true);
setError(null);
setMessages(prev => [...prev, { role: 'user', content: message }]);
try {
const response = await aiRef.current.chat(message);
setMessages(prev => [...prev, {
role: 'assistant',
content: response.content
}]);
return response;
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, []);
return { messages, sendMessage, loading, error, ai: aiRef.current };
}
컴포넌트에서 사용
function ChatBot() {
const { messages, sendMessage, loading, error } = useAIKit({
provider: 'openai',
apiKey: process.env.REACT_APP_API_KEY,
enableCache: true
});
const [input, setInput] = useState('');
const handleSend = async () => {
if (!input.trim()) return;
await sendMessage(input);
setInput('');
};
return (
<div>
{messages.map((msg, i) => (
<div key={i} className={msg.role}>{msg.content}</div>
))}
{loading && <div>응답 생성 중...</div>}
{error && <div className="error">{error}</div>}
<input value={input} onChange={e => setInput(e.target.value)} />
<button onClick={handleSend} disabled={loading}>전송</button>
</div>
);
}
Context API로 전역 관리
const AIKitContext = createContext(null);
function AIKitProvider({ children, config }) {
const aikit = useAIKit(config);
return (
<AIKitContext.Provider value={aikit}>
{children}
</AIKitContext.Provider>
);
}
// 어디서든 사용
function AnyComponent() {
const { sendMessage, messages } = useContext(AIKitContext);
}
Vue 3 연동
Composable
// useAIKit.js
import { ref, shallowRef } from 'vue';
export function useAIKit(config) {
const ai = shallowRef(new AIKit(config));
const loading = ref(false);
const error = ref(null);
const messages = ref([]);
async function sendMessage(message) {
loading.value = true;
error.value = null;
messages.value.push({ role: 'user', content: message });
try {
const response = await ai.value.chat(message);
messages.value.push({
role: 'assistant',
content: response.content
});
return response;
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
}
return { messages, sendMessage, loading, error, ai };
}
컴포넌트에서 사용
<template>
<div>
<div v-for="(msg, i) in messages" :key="i" :class="msg.role">
{{ msg.content }}
</div>
<div v-if="loading">응답 생성 중...</div>
<input v-model="input" @keyup.enter="handleSend" />
<button @click="handleSend" :disabled="loading">전송</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useAIKit } from './useAIKit';
const { messages, sendMessage, loading } = useAIKit({
provider: 'openai',
apiKey: import.meta.env.VITE_API_KEY
});
const input = ref('');
async function handleSend() {
if (!input.value.trim()) return;
await sendMessage(input.value);
input.value = '';
}
</script>
프레임워크 비교
| 항목 | React | Vue 3 |
|---|---|---|
| 패턴 | Custom Hook | Composable |
| 상태 관리 | useState + useRef | ref + shallowRef |
| 전역 관리 | Context API | Provide/Inject |
| 번들 크기 추가 | +2KB | +2KB |
| 성능 차이 | 없음 | 없음 |
AIKit 자체는 프레임워크에 독립적이므로 번들 크기와 성능에 미치는 영향이 거의 없다.
핵심 포인트
- AIKit 인스턴스는 한 번만 생성한다 — React에서는
useRef, Vue에서는shallowRef - 대화 이력은 프레임워크 상태로 관리한다 —
useState/ref - 로딩과 에러 상태를 분리한다 — UX 품질을 위해
- 환경 변수로 API 키를 관리한다 — 하드코딩 금지
마무리
React든 Vue든 AIKit 사용법은 동일하다. 프레임워크의 상태 관리 패턴으로 감싸기만 하면 된다. 순수 JavaScript로 만든 이유가 여기서 빛을 발한다.
다음 편에서는 AI API 비용을 90% 줄이는 최적화 전략을 다룬다.
기술 스택: React, Vue 3, AIKit, JavaScript
소스 코드: GitHub
반응형
'프로젝트 > AIKit' 카테고리의 다른 글
| AIKit #8 - 사이드 프로젝트 개발 회고 (1) | 2026.02.09 |
|---|---|
| AIKit #7 - AI API 비용 90% 줄이기 (0) | 2026.02.09 |
| AIKit #5 - PHP 프로젝트에서 AIKit 연동하기 (0) | 2026.02.08 |
| AIKit #4 - 5분 만에 AI 챗봇 만들기 (0) | 2026.02.07 |
| AIKit #3 - QA 개발자가 만든 AI 라이브러리 (0) | 2026.02.07 |