
@frontend ์ฌ๊ธฐ;์ ์ปจํ ์คํธ๋ก store๋ฅผ ๋ฐ๋์ 1๊ฐ๋ง ๋ง๋ค๊ณ , ์ด๊ฒ์ ๊ด๋ฆฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก zustand๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํด. ํด๋น๊ณผ์ ์ ๋ํด ์ง์ ์คํํ์ง๋ ๋ง๊ณ ์ ๋ต์ ์์ฑํด์ค
Zustand ๋จ์ผ Store ์ ๋ต
1. ํ๋ก์ ํธ ๊ตฌ์กฐ ์ค๊ณ
2. ์์กด์ฑ ์ค์น
- zustand ์ค์น (ํ์ฌ ๋ฏธ์ค์น)
- TypeScript ํ์ ์ ๋ด์ฅ
3. Store ๊ตฌ์กฐ ์ค๊ณ ์์น
3.1 ๋จ์ผ Store ํจํด
- ํ๋์ zustand store๋ง ์์ฑ (useStore)
- ์ฌ๋ฌ ๋๋ฉ์ธ ์ํ๋ store ๋ด๋ถ์์ ์ฌ๋ผ์ด์ค๋ก ๋ถ๋ฆฌ
- ์: chat, ui, user ๋ฑ
3.2 Store ์ฌ๋ผ์ด์ค ๊ตฌ์กฐ ์์
4. ๊ตฌํ ๋จ๊ณ
Step 1: ํ์ ์ ์
- types/store.ts์ ์ ์ฒด store ํ์ ์ ์
- ํ์ฌ page.tsx์ Message ์ธํฐํ์ด์ค ํฌํจ
Step 2: Store ์์ฑ
- store/useStore.ts์์ create๋ก ๋จ์ผ store ์์ฑ
- ์ด๊ธฐ ์ํ์ actions ์ ์
- ํ์ฌ page.tsx์ ๋ก์ง์ store actions๋ก ์ด๋
Step 3: Store Export
- store/index.ts์์ useStore๋ง export
- ๋ค๋ฅธ store ํ์ผ ์์ฑ ๊ธ์ง
Step 4: ์ปดํฌ๋ํธ ๋ง์ด๊ทธ๋ ์ด์
- page.tsx์ useState๋ฅผ useStore๋ก ๊ต์ฒด
- selector ํจํด์ผ๋ก ํ์ํ ์ํ๋ง ๊ตฌ๋
5. Store ์ฌ์ฉ ํจํด
5.1 Selector ํจํด
5.2 Actions ์ฌ์ฉ
- ๋ชจ๋ ์ํ ๋ณ๊ฒฝ์ actions๋ก๋ง ์ํ
- ์ง์ ์ํ ์์ ๊ธ์ง
6. Next.js App Router ๊ณ ๋ ค์ฌํญ
6.1 Server/Client ์ปดํฌ๋ํธ
- Store๋ Client Component์์๋ง ์ฌ์ฉ
- 'use client' ๋๋ ํฐ๋ธ ํ์
6.2 SSR ํธํ์ฑ
- zustand๋ ๊ธฐ๋ณธ์ ์ผ๋ก SSR ํธํ
- ์ด๊ธฐ ์ํ๋ ํ์ด๋๋ ์ด์ ์ ๋๊ธฐํ
7. ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ต
7.1 ํ์ฌ ์ํ ๋ถ์
- page.tsx์ ์ํ:
- messages: Message[]
- input: string
7.2 ๋ง์ด๊ทธ๋ ์ด์ ์์
- Store ํ์ ์ ์
- Store ์์ฑ ๋ฐ actions ๊ตฌํ
- page.tsx์์ store ์ฌ์ฉ์ผ๋ก ๋ณ๊ฒฝ
- ํ ์คํธ ๋ฐ ๊ฒ์ฆ
8. ํ์ผ ์์ฑ ๊ณํ
- src/types/store.ts - ํ์ ์ ์
- src/store/useStore.ts - ๋จ์ผ zustand store
- src/store/index.ts - export ์ง์ ์
9. ์ฃผ์์ฌํญ
- ๋จ์ผ store ์์น: useStore.ts ์ธ ๋ค๋ฅธ store ํ์ผ ์์ฑ ๊ธ์ง
- ํ์ ์์ ์ฑ: TypeScript๋ก ํ์ ์ ์
- ์ฑ๋ฅ: selector๋ก ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง
- ํ์ฅ์ฑ: ์ฌ๋ผ์ด์ค ํจํด์ผ๋ก ๋๋ฉ์ธ๋ณ ๊ด๋ฆฌ
10. ๊ฒ์ฆ ์ฒดํฌ๋ฆฌ์คํธ
- [ ] zustand ํจํค์ง ์ค์น ํ์ธ
- [ ] store/useStore.ts ๋จ์ผ ํ์ผ ์กด์ฌ ํ์ธ
- [ ] store/index.ts์์ ๋จ์ผ export ํ์ธ
- [ ] ๋ค๋ฅธ store ํ์ผ ์์ ํ์ธ
- [ ] ์ปดํฌ๋ํธ์์ useStore ์ฌ์ฉ ํ์ธ
- [ ] ํ์ ์๋ฌ ์์ ํ์ธ

<!-- 79f2f66b-147a-4a97-81fb-958c5d709f55 692e06e3-c0d1-4ed0-9fb1-c8d97512fe1c -->
# esgseed → frontend ํตํฉ ๋ฐ ๋จ์ผ React Context/Zustand ์ ๋ต
## 1. ๋ชฉํ ์ํ ์ ์
- **์ฑ์ ํ๋๋ง ์ ์ง**: `frontend`(Next.js App Router)๊ฐ ์ต์ข
SPA์ ์ง์
์ ์ด ๋จ
- **esgseed** ๋๋ ํ ๋ฆฌ๋ **ํ์ด์ง/์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ญํ **๋ง ํ๊ณ , ๋ณ๋ Vite ์ฑ์ผ๋ก ๋์ํ์ง ์๊ฒ ์ ๋ฆฌ
- **์ ์ญ ์ํ ๋ ์ด์ด๋ ํ๋**:
- `frontend/src/store/useStore.ts` (์ด๋ฏธ ๊ตฌ์ถ๋ Zustand ์คํ ์ด)
- ๋๋ ํ์ ์ ์ด ์์ React Context Provider๋ฅผ ์๊ฒ ์์์ ์ฌ์ฉ
## 2. esgseed ๊ตฌ์กฐ ๋ถ์ ๋ฐ ๋ถ๋ฅ
1. `esgseed/src` ์๋ ํ์ผ๋ค์ ์ญํ ๋ณ๋ก ๋ถ๋ฅ
- `pages` ์ฑ๊ฒฉ ์ปดํฌ๋ํธ (์ ์ฒด ํ๋ฉด ๊ตฌ์ฑ)
- `components` ์ฑ๊ฒฉ UI ์กฐ๊ฐ (๋ฒํผ, ์นด๋, ๋ฆฌ์คํธ ๋ฑ)
2. ๋ผ์ฐํ
์์กด์ฑ ํ์ธ
- `react-router`, `vite` ์ ์ฉ ํ
/์ปดํฌ๋ํธ ์ฌ์ฉ ์ฌ๋ถ ์ฒดํฌ
- ์ ์ญ ์ํ/Context ์ฌ์ฉ ์ฌ๋ถ ์ฒดํฌ (์: `useContext`, `Redux`, `Recoil` ๋ฑ)
๊ฒฐ๊ณผ์ ๋ฐ๋ผ **ํ์ด์ง์ ์์ ์ปดํฌ๋ํธ**๋ฅผ ๋ถ๋ฆฌํด์ ์ฎ๊ธฐ๋ ์ ๋ต์ ์ธ์.
## 3. ํตํฉ ๋์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ์ค๊ณ
`frontend` ํ๋ก์ ํธ ๋ด๋ถ์์ esgseed ์ปดํฌ๋ํธ๋ฅผ ์์ฉํ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ ์:
```bash
frontend/
src/
store/
useStore.ts # ๋จ์ผ Zustand ์คํ ์ด (์ด๋ฏธ ์กด์ฌ)
lib/
api.ts # ๋ฐฑ์๋ ํธ์ถ ์ ํธ๋ฆฌํฐ
features/
esgseed/
components/ # esgseed์์ ์จ ์์ UI ์ปดํฌ๋ํธ๋ค
pages/ # esgseed ํ์ด์ง ๋ ์ด์์/์ปจํ
์ด๋
```
- `features/esgseed/components`: Next, Vite์ ์์กดํ์ง ์๋ ์์ React ์ปดํฌ๋ํธ๋ก ์ ๋ฆฌ
- `features/esgseed/pages`: ์ค์ Next `app` ๋ผ์ฐํธ์์ importํด์ ์ฌ์ฉํ๋ ์ปจํ
์ด๋ ์ปดํฌ๋ํธ
## 4. esgseed ์ปดํฌ๋ํธ ์ด๊ด ์ ๋ต
### 4.1 ์์ UI ์ปดํฌ๋ํธ ์ด๋
1. Vite ์ ์ฉ ์ฝ๋(์: `import.meta.env`, `react-router-dom` ๋ฑ)๋ฅผ ์ ๊ฑฐํ๊ฑฐ๋ Next์ ๋ง๊ฒ ์นํ
2. ๊ฐ ์ปดํฌ๋ํธ๋ฅผ `frontend/src/features/esgseed/components`๋ก ๋ณต์ฌ/์ด๋
3. ๊ฒฝ๋ก/๋ณ์นญ ์ ๋ฆฌ
- `import X from '../../components/X'` → `import X from '@/features/esgseed/components/X'`
### 4.2 ํ์ด์ง ๋ ๋ฒจ ์ปดํฌ๋ํธ ํฌํ
1. `esgseed`์ ํ์ด์ง ๋จ ์ปดํฌ๋ํธ๋ฅผ `frontend/src/features/esgseed/pages`๋ก ์ด๋
2. Next ๋ผ์ฐํธ ์์ฑ:
- ์: esgseed์ `/dashboard` ํ์ด์ง → `frontend/src/app/dashboard/page.tsx`
- ํ์ผ ๋ด์ฉ:
```tsx
'use client';
import DashboardPage from '@/features/esgseed/pages/DashboardPage';
export default function Page() {
return <DashboardPage />;
}
```
3. ํ์ด์ง ํ์ผ(`app/.../page.tsx`)์ Next ๊ท์น์ ๋ฐ๋ผ `'use client'` ์ฌ๋ถ๋ฅผ ๊ฒฐ์
- Zustand/๋ธ๋ผ์ฐ์ API ์ฌ์ฉ ์ `'use client'` ์ ์ง
## 5. ๋จ์ผ ์ ์ญ ์ํ(React Context + Zustand) ์ค๊ณ
### 5.1 Zustand๋ฅผ ๋จ์ผ ์์ค ์ค๋ธ ํธ๋ฃจ์ค๋ก ์ฌ์ฉ
- ์ด๋ฏธ ์กด์ฌํ๋ `src/store/useStore.ts`๋ฅผ ํ์ฅํ์ฌ esgseed์์๋ ํ์ํ ์ํ/์ก์
์ ์ถ๊ฐ
- esgseed ์ปดํฌ๋ํธ์์๋ ๋ชจ๋ `useStore`๋ง ์ฌ์ฉํ๋๋ก ํต์ผ
์์:
```ts
// esgseed์์ ํ์๋ก ํ๋ state
interface AppState {
// ๊ธฐ์กด soccer ๊ด๋ จ ์ํ...
// esgseed ๊ณตํต UI ์ํ
theme: 'light' | 'dark';
sidebarOpen: boolean;
setTheme: (theme: 'light' | 'dark') => void;
toggleSidebar: () => void;
}
```
### 5.2 ์ ํ์ React Context ๋ํผ (์ํ๋ฉด)
- ๋ง์ฝ esgseed ์ชฝ์ด `useContext` ๊ธฐ๋ฐ์ผ๋ก ์ค๊ณ๋์ด ์๋ค๋ฉด:
1. ์๋ก์ด `AppContext`๋ฅผ ๋ง๋ค๊ณ ๋ด๋ถ ๊ตฌํ์์ **Zustand๋ฅผ ์์**
2. ๊ธฐ์กด esgseed ์ปดํฌ๋ํธ๋ `useContext(AppContext)`๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉ
3. Context Provider ๊ตฌํ ์:
```tsx
'use client';
import { createContext, useContext } from 'react';
import { useStore } from '@/store/useStore';
const AppContext = createContext<ReturnType<typeof useStore> | null>(null);
export function AppProvider({ children }: { children: React.ReactNode }) {
const store = useStore();
return <AppContext.Provider value={store}>{children}</AppContext.Provider>;
}
export function useAppContext() {
const ctx = useContext(AppContext);
if (!ctx) throw new Error('useAppContext must be used within AppProvider');
return ctx;
}
```
- `src/app/layout.tsx` ํน์ ์์ client ์ปดํฌ๋ํธ์์ `AppProvider`๋ก ์ ์ฒด ๊ฐ์ธ๊ธฐ
## 6. Next ์ฑ์ Provider ์ฐ๊ฒฐ
1. `src/app/layout.tsx`๊ฐ **์๋ฒ ์ปดํฌ๋ํธ**์ผ ๊ฒฝ์ฐ:
- ๋ณ๋ `AppProviders` client ์ปดํฌ๋ํธ ์์ฑ:
```tsx
// src/app/AppProviders.tsx
'use client';
import { AppProvider } from '@/store/AppContext';
export default function AppProviders({ children }: { children: React.ReactNode }) {
return <AppProvider>{children}</AppProvider>;
}
```
- `layout.tsx`์์:
```tsx
import AppProviders from './AppProviders';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body>
<AppProviders>{children}</AppProviders>
</body>
</html>
);
}
```
2. ์ด๋ ๊ฒ ํ๋ฉด `frontend`์ esgseed์์ ์จ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ **๋์ผํ Zustand/Context ์ํ**๋ฅผ ๊ณต์
## 7. esgseed ๋น๋/์ค์ ์ ๋ฆฌ
1. esgseed์ **Vite ๊ด๋ จ ํ์ผ** ์ ๊ฑฐ/๋ฌดํจํ:
- `esgseed/vite.config.ts`, `esgseed/index.html`, `esgseed/src/main.tsx` ๋ฑ
- `esgseed/package.json`์์ ์คํฌ๋ฆฝํธ๋ ์ ์ง์ ์ผ๋ก ์ฌ์ฉ ์ค๋จ
2. ํ์ํ๋ค๋ฉด esgseed๋ฅผ **ํจํค์งํ** (์: `packages/esgseed-ui`)ํด์ ์ฌ์ฌ์ฉํ ์๋ ์์ง๋ง,
ํ์ฌ๋ ๋จ์ํ `frontend/src/features/esgseed`๋ก ํฉ์น๋ ์ชฝ์ด ๊ฐ๋จ
## 8. ํ
์คํธ ํ๋ก์ฐ
1. `pnpm build` (frontend ๋ฃจํธ)๋ก ํ์
/๋น๋ ์ค๋ฅ ํ์ธ
2. `pnpm dev` ์คํ ํ:
- esgseed์์ ์จ ํ์ด์ง ๋ผ์ฐํธ๋ค ์ ์ ๋์ ์ฌ๋ถ ํ์ธ
- Zustand/Context ์ํ๊ฐ ํ ํ์ด์ง์ esgseed ํ์ด์ง ๊ฐ์ ๊ณต์ ๋๋์ง ํ์ธ
3. ๋ธ๋ผ์ฐ์ DevTools๋ก ๋ฆฌ๋ ๋๋ง/์ํ ๋ณํ ํ์ธ
## 9. ๋จ๊ณ๋ณ ์์ฝ
1. esgseed ์ปดํฌ๋ํธ๋ฅผ `frontend/src/features/esgseed`๋ก ์ด๋
2. Zustand Store(`src/store/useStore.ts`)์ esgseed ๊ด๋ จ ์ํ/์ก์
์ถ๊ฐ
3. ํ์ํ ๊ฒฝ์ฐ React Context ๋ํผ(AppContext) ์ถ๊ฐ
4. `app/layout.tsx`์์ Provider ์ฐ๊ฒฐ
5. esgseed ํ์ด์ง๋ฅผ Next `app` ๋ผ์ฐํธ์ ๋งคํ
6. Vite/Vite ์ ์ฉ ์ค์ ์ ๊ฑฐ ๋ฐ esgseed๋ฅผ ์์ ์ปดํฌ๋ํธ ๋ชจ์์ผ๋ก ์ ๋ฆฌ
### To-dos
- [ ] pnpm์ผ๋ก zustand ์์กด์ฑ ์ค์น
- [ ] src/store/index.ts ์์ฑ - ํ์
, ์ํ, actions ์ ์
- [ ] page.tsx์ useState๋ฅผ useStore๋ก ๋ง์ด๊ทธ๋ ์ด์
- [ ] soccer/page.tsx์ ๋ก์ปฌ ์ํ๋ฅผ Store๋ก ์ด์
- [ ] pnpm dev๋ก ๋์ ํ์ธ ๋ฐ DevTools ์ ๊ฒ
**์ด๋๋ก ์ปค์์๊ฒ ๋งํ๊ณ ์ ๋ฆฌํ๋ฉด์ ์งํํ๊ธฐ


๊ฐ์ธ ํ๋ก์ ํธ๋ ํํํ ํ๊ธฐ!
'Project ESG+AI > [์ผ์ KPMG]ESG ๋ฐ์ดํฐ ํ์ฉ ํ์คํ ๊ฐ๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| 32์ผ์ฐจ. ๋๋ฉ์ธ ์ฐ๊ฒฐํ๊ธฐ & ๋ฏธ๋ค์จ์ด (0) | 2025.11.21 |
|---|---|
| 31์ผ์ฐจ. ๊น ๋ธ๋์น ๋ง๋ค๊ธฐ (0) | 2025.11.20 |
| 29์ผ์ฐจ. ์๋ฌ ์ก๊ณ ํฐ๋ฏธ๋์ ์ ๋ ฅ๊ฐ ์ถ๋ ฅ๋๊ฒ ํ๊ธฐ, ๋์ปค ์ปดํฌ์ฆ ์ (1) | 2025.11.18 |
| 28์ผ์ฐจ. (0) | 2025.11.17 |
| 27์ผ์ฐจ. (0) | 2025.11.14 |