9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
5.0 KiB
5.0 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-l-component-lifecycle-hooks | Lifecycle Hooks | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Lifecycle Hooks
매 한 줄
"매 컴포넌트의 생애주기 훅". mount/update/unmount 시점에 부수효과를 거는 표준 메커니즘. React 는
useEffect단일화, Vue/Angular/Svelte 는 명명된 훅 제공.
매 핵심
매 공통 phase
- Create: instance 생성, props 수신.
- Mount: DOM 진입 — 이벤트 바인딩, 데이터 fetch.
- Update: state/props 변경 — derived 갱신.
- Unmount: DOM 제거 — cleanup (timer, listener, subscription).
- Error: 자식 throw 잡기.
매 framework 매핑
| Phase | React | Vue 3 | Angular | Svelte |
|---|---|---|---|---|
| Mount | useEffect(fn, []) |
onMounted |
ngOnInit |
onMount |
| Update | useEffect(fn, [dep]) |
watch |
ngOnChanges |
$: reactive |
| Unmount | return cleanup | onUnmounted |
ngOnDestroy |
onDestroy |
| Error | ErrorBoundary |
onErrorCaptured |
ErrorHandler |
(없음, try/catch) |
매 React 19 메모
- StrictMode 가
useEffect를 dev 에서 2회 실행 → cleanup 필수. - Server Component 는 lifecycle 없음 (그냥 async function).
usehook 으로 promise 직접 read 가능.
💻 패턴
React: 마운트시 fetch + cleanup
useEffect(() => {
const ctrl = new AbortController();
fetch(`/api/user/${id}`, { signal: ctrl.signal })
.then(r => r.json()).then(setUser);
return () => ctrl.abort();
}, [id]);
React: subscribe pattern
useEffect(() => {
const sub = store.subscribe(setState);
return () => sub.unsubscribe();
}, []);
Vue 3 Composition API
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
const data = ref(null);
let timer: number;
onMounted(async () => {
data.value = await fetch("/api").then(r => r.json());
timer = setInterval(refresh, 5000);
});
onUnmounted(() => clearInterval(timer));
</script>
Angular standalone component
@Component({ selector: "app-x", standalone: true, template: "..." })
export class XComponent implements OnInit, OnDestroy {
private sub?: Subscription;
constructor(private svc: DataService) {}
ngOnInit() {
this.sub = this.svc.stream$.subscribe(v => (this.value = v));
}
ngOnDestroy() { this.sub?.unsubscribe(); }
}
Svelte 5 (with runes)
<script>
import { onMount, onDestroy } from "svelte";
let count = $state(0);
let timer;
onMount(() => { timer = setInterval(() => count++, 1000); });
onDestroy(() => clearInterval(timer));
</script>
React custom hook (encapsulate lifecycle)
function useInterval(cb: () => void, ms: number) {
const ref = useRef(cb);
useEffect(() => { ref.current = cb; }, [cb]);
useEffect(() => {
const id = setInterval(() => ref.current(), ms);
return () => clearInterval(id);
}, [ms]);
}
Error boundary (React)
class Boundary extends React.Component {
state = { err: null };
static getDerivedStateFromError(err) { return { err }; }
componentDidCatch(err, info) { logger.error(err, info); }
render() {
return this.state.err ? <Fallback /> : this.props.children;
}
}
매 결정 기준
| 작업 | 적절한 훅 (React) |
|---|---|
| 1회 fetch on mount | useEffect(fn, []) |
| dep 변경시 refetch | useEffect(fn, [dep]) |
| DOM 측정 | useLayoutEffect |
| 외부 store 구독 | useSyncExternalStore |
| Render 동안 동기화 | derived state, NOT effect |
기본값: 가능하면 effect 안 쓰고 derived 로 처리. effect 는 "외부 시스템 동기화" 전용.
🔗 Graph
- 변형: useEffect, ngOnInit, onMount
- 응용: Data-Fetching
- Adjacent: Custom Hooks, Error Boundaries, Server Components
🤖 LLM 활용
언제: 외부 시스템(timer, socket, listener) 결합, mount-once init, prop-driven refetch. 언제 X: pure 계산 — useMemo/derived 로 충분, useEffect 남용은 안티패턴.
❌ 안티패턴
- Effect 안 dep 누락: stale closure → 버그 끝판왕.
- Cleanup 미작성: timer/listener leak, StrictMode 에서 즉시 들킴.
- 상태를 effect 로 동기화: derived state 가 정답.
- Async useEffect 함수:
useEffect(async () => ...)안 됨. 안에서 async fn 호출. - ngOnChanges 에서 setState 무한 루프: 입력 비교 필수.
🧪 검증 / 중복
- React docs (You Might Not Need an Effect), Vue 3 / Angular / Svelte 5 공식 문서.
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 4 framework 매핑표, useEffect 안티패턴, Svelte 5 runes |