2025-05-09 count, todolist

rogie·2025년 5월 29일

likelion-posting

목록 보기
10/10

🧠 배운 점 & 정리

COUNT

counter/06/counter/07 차이점

  • index.js
항목counter/06/index.jscounter/07/index.js
console.log없음Header, Counter, App 함수 호출 시 로그 출력
상태 관리 방식지역 변수 count 사용 후, 이벤트 핸들러 내에서 document.querySelector(...).textContent로 DOM 직접 업데이트Reaction.useState 훅으로 상태 저장, setCount 호출 시 내부적으로 자동 리렌더링
이벤트 핸들러handleDown/handleUp/handleReset에서 직접 count 조작 후 수동으로 텍스트 갱신동일한 핸들러 이름 사용하나, 내부에서는 setCount만 호출해 리렌더링에 위임
렌더링 동작최초 렌더링 이후 상태 변경 시 수동 업데이트 필요상태 변경 시 컴포넌트 전체가 자동으로 재 렌더링
  • reaction.js
항목counter/06/reaction.jscounter/06/reaction.js
전역 변수 선언전역 상태 변수 없음_root, _stateValue 전역으로 선언
createRoot 구현render(appFn) 호출 시 단순히 appendChild(appFn()) 실행컴포넌트 함수 캐싱 (_appComponent = _appComponent **??** appFn)기존 자식 제거
(firstChild?.remove()) 후 재렌더
상태 관리 (useState)없음useState(initialValue) 구현_stateValue 보관 및 setValue 호출 시 render() 트리거
상태 초기화 방식해당 없음_stateValue = _stateValue ?? initialValue
렌더링 동작최초 렌더만 지원상태 변경 감지 시 (Object.is 비교 후) render() 재호출

?? vs || 연산자
  • || 논리 OR 연산자

    • 왼쪽 값이 거짓(falsy) 으로 평가되면(예: false, 0, "", null, undefined, NaN) → 오른쪽으로 대체
  • ?? (Nullish Coalescing) 연산자 (null 병합 연산자)

    • 왼쪽 값이 오직 null 또는 undefined일 때만 → 오른쪽으로 대체
    • false, 0, "", NaN 등은 유효한 값으로 그대로 유지
  • 예시보기

    function test(val) {
      const initial = "기본값";
      console.log(val || initial, " ← || 결과");
      console.log(val ?? initial, " ← ?? 결과");
    }
    
    test(false);   // 기본값 ← ||    , false ← ??
    test(0);       // 기본값 ← ||    , 0     ← ??
    test("");      // 기본값 ← ||    , ""    ← ??
    test(null);    // 기본값 ← ||    , 기본값 ← ??
    test(undefined); // 기본값 ← ||  , 기본값 ← ??

TODOLIST

  • 파일별 차이점
구분todolist/06/index.jstodolist/07/index.jstodolist/08/index.js
주요 목적단일 App 함수로 Reaction.createElement() 활용한 UI 구성UI를 기능별 컴포넌트 함수로 분리useState 도입으로 상태 변경 시 화면 리렌더링
컴포넌트 구조App 하나만 정의Header, Todo, Footer, TodoItem, TodoInput, TodoList 분리07과 동일한 분리 + 각 컴포넌트에 props/state 적용
TodoItem 정의App 내 하드코딩인자 없는 재사용 함수{ item } 파라미터 받아 동적 데이터 렌더링
TodoList 구현 방식App에서 static 요소 하드코딩Reaction.createElement("ul",…, TodoItem)로 함수 참조 전달itemList.map(item => TodoItem({ item }))로 리스트 매핑
상태 관리없음없음const [itemList, setItemList] = Reaction.useState(inititemList)
이벤트 처리 및 props없음없음TodoInputhandleAddKeydown, handleAdd props로 전달, onkeydown/onclick 설정
동적 기능없음없음아이템 추가(addItem), 삭제(deleteItem), 완료 토글(toggleDone) 기능 포함
파일 경로 표시 방식location.href.split("/ch")[1] 하드코딩동일동일

todolist/08/index.js 로 보는 파일 구조 설명
- 초기 값 및 Reaction 유틸 불러오기
    - `inititemList`에 기본 할 일 배열을 정의
    - `Reaction.useState` 훅을 통해 `itemList` 상태와 갱신 함수 `setItemList`를 선언
- Header 컴포넌트
    - 앱 제목과 현재 파일 경로를 `<h1>`/`<span id="filepath">`로 표시
    - `location.href.split("/ch")[1]` 로 URL에서 파일명만 추출
- TodoInput 컴포넌트
    - 텍스트 입력창(`input`)과 추가 버튼(`button`)을 렌더링
    - 두 가지 이벤트 핸들러를 props로 받음
        - `handleAddKeydown` : 입력창에서 Enter 키 누르면 호출
        - `handleAdd` : 추가 버튼 클릭 시 호출
- TodoItem 컴포넌트
    - 개별 할 일 객체를 props로 받아서 `<li>`로 출력
    - 클릭하면 완료 상태 전환(`toggleDone`), 옆의 삭제 버튼 클릭 시 해당 항목 삭제(`deleteItem`)
- TodoList 컴포넌트
    - `itemList` 배열을 `map`으로 순회하며
        - 각 요소를 `TodoItem({ item })` 형태로 렌더링
- Footer 컴포넌트
    - 간단한 저작권 또는 추가 정보 표시
- App 컴포넌트 전체 구성
    - 위의 컴포넌트들을 한데 모아 루트 `<div>` 안에 렌더링
    - 상태 조작 함수 정의
        - `addItem(title)` : 새 아이템 객체를 `itemList`에 추가
        - `deleteItem(num)` : 필터링으로 해당 아이템 제거
        - `toggleDone(num)` : 클릭된 아이템의 num을 조회한 후 `done` 속성 토글
        - `handleAddKeydown(e)` : Enter 키일 때 `addItem` 호출
        - `handleAdd()` : 버튼 클릭 시 `addItem` 호출
    - 이들 함수를 `TodoInput`, `TodoItem` 등에 props로 전달
- DOM에 붙이기
    - `document.querySelector("#root")` 로 루트 요소 선택
    - `Reaction.render(App(), root)` 또는 `root.appendChild(App())` 호출해 화면에 표시
- 사용자 상호작용 흐름
    - 페이지 로드 → `inititemList` 기반 렌더링
    - 입력창에 텍스트 입력 후
        - Enter 누르거나 추가 버튼 클릭 → `addItem` → `setItemList` → 자동 리렌더링
    - 각 할 일 항목 클릭 시 `toggleDone` → 시각적 스타일 변경
    - 삭제 버튼 클릭 시 `deleteItem` → 해당 항목 제거 → 리렌더링

  • 전체 구도
        ┌───────── App ──────────┐  ← 최상위 컴포넌트
        │           │            │
      Header       Todo        Footer  ← 주요 섹션 컴포넌트들
                    │
                ┌───┴────┐             ← Todo 내부 구조
          TodoInput   TodoList         ← 입력부와 목록부
                         │
                      TodoItem         ← 개별 할일 아이템
  • 함수로 보는 파일 구조
App()                                ← 최상위 함수 (파라미터 없음)
├─ addItem(title)                    ← 새 아이템 추가 함수 (text: string)
├─ deleteItem(num)                   ← 아이템 삭제 함수 (id: string)
├─ toggleDone(num)                   ← 완료 토글 함수 (id: string)
├─ handleAddKeydown(e)               ← 엔터 키 이벤트 핸들러 (e: KeyboardEvent)
├─ handleAdd()                       ← 추가 버튼 클릭 핸들러 (파라미터 없음)
├─ Header()                          ← 헤더 컴포넌트 함수 (파라미터 없음)
├─ TodoInput(                        ← 입력부 컴포넌트
│     {                           
│       handleAddKeydown,           ← props.handleAddKeydown: function
│       handleAdd                   ← props.handleAdd: function
│     })
├─ TodoList(                         ← 목록부 컴포넌트
│     { itemList }                 ← props.itemList: array of Todo 객체
│   )
│    └─ TodoItem(                    ← 개별 할일 아이템 컴포넌트
│         { item }                 ← props.item: Todo 객체
│       )
└─ Footer()                          ← 푸터 컴포넌트 함수 (파라미터 없음)

🔗 배웠던 파일


❓ 생긴 질문 / 더 알아볼 것

  • 우와...너무 어렵다...이게 뭘까
  • 분명 같은 한국어인데 한국어처럼 들리지 않아
  • 오늘 오타 고치고 잘못 들어간 코드만 고친 하루였다
  • 배운건 없었던 느낌?
profile
front-end를 꿈꿉니다

0개의 댓글