실습내용
리액트의 핵심 부분을 감성일기장이라는 심플한 프로젝트 실습을 통하여 배우고 익힌다.
실습과정
useState
상태를 관리하는 훅
ex) DiaryEditor.js 컴포넌트 일부
date 현제 데이터
setDate 업데이트될 데이터
useState() = 기본값(현제 날짜 기본값으로 셋팅)
getStringDate 함수 : 생성된 날짜를 특정 포맷으로 변환 해주는 공용 함수
input 태그가 change 될때 e.target.value 데이터 값으로 setDate 에 넣어 날짜 상태값 업데이트
date 는 업데이트 된 값이 들어오므로 value 값에 date 표시.
*훅 이란 함수형 컴포넌트에서 상태(state) 및 생명주기(lifecycle) 기능등을 사용할 수 있게 해주는 기능
useRef
DOM 요소나 컴포넌트 인스턴스를 직접 참조할 수 있게 해주는 훅
ex) DiaryEditor.js 컴포넌트 일부
contentRef 변수에 useRef 훅 셋팅
작성 완료 section 태그 클릭시 prop으로 전달받은 handleSumbmit함수 실행
content.length 길이가 1보다 작을경우 contentRef.current.focus() 이용하여 포커스 이동
current 프로퍼티를 이용해 해당 요소를 접근 할 수 있다.
contentRef 연결되어 있는 태그에 포커스 이동
* ref 프로퍼티 이용하여 prop으로 useRef 훅 연결 가능
props
부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 사용
props가 바뀔때 마다 리랜더링이 발생 , 내부모요소가 리랜더 되면 자식 컴포넌트로 리랜더 된다.
ex) Home.js , MyHeader.js 컴포넌트 일부
Home.js 컴포넌트에서 headText에 현제 년,월 을 넣어준다.
Home.js 컴포넌트에서 랜더링시 MyHeader 컴포넌트를 불러와 props에 위 그림과 같이 headText를 넣어준다.
위 그림에 leftChild, rightChild 처럼 props 값으로 컴포넌트를 전달할 수도 있다.
MyHeader.js 컴포넌트는 위 그림과 같이 headText, leftChild, rightChild 를 props로 전달 받을 수 있다.
구조 분해 할당
객체나 배열의 속성을 개별 변수에 쉽게 할당할 수 있게 한다.
ex) DiaryList.js , DiaryItem.js 컴포넌트 일부
DiaryList.js 컴포넌트에서 sortType 에 따라 오름차순 내림차순 정렬 하여 리턴 해주는 함수(getProcessedDiaryList)
getProcessedDiaryList 함수로 정렬 및 필터 된 json 데이터 리턴 받아서 DiaryItem컴포넌트에 에 props로 넣어주기
이때 스프레드 연산자 사용하여 넣기 스프레드 연산자 설명은 다음 항목에서.
* 리스트에는 반드시 key 프로퍼티를 부여하여 엘리먼트를 고유하게 식별하게 할 수 있어야 한다.
DiaryList.js 컴포넌트에서 스프레드연산자로 전달한 데이터( it )을 DiaryItem.js 컴포넌트에서 속성명만 적어 쉽게 접근 가능 하다. (구조 분해 할당)
스프레드 연산자
객체나 배열을 복사하거나 합칠 때 사용
ex) DiaryList.js
getProcessedDiaryList 로 반환받은 리스트 데이터를 map으로 순회하면서 it에 저장 it에 저장된 it 객체 구조는 아래와 같다
it 객체의 모든속성값을 {...it} 로 한번에 DiaryItem에 전달한다.(스프레드 연산자)
라이프사이클 제어(useEffect)
컴포넌트의 라이프사이클 동안 특정 작업을 수행할 수 있게 해주는 훅
라이프 사이클은 크게 탄생(Mount), 변화(Update), 죽음(UnMount) 3가지로 구분된다.
사용법
LifeCycle.js 컴포넌트(실습프로젝트와 별개)
Lifecycle.js 컴포넌트에서 위 그림과 같이 Dependency Array(의존성 배열)이 빈값인 경우 첫 한번만 실행하게 된다.
탄생(Mount),
Dependency Array(의존성 배열)이 없는 경우는 랜더링 될때마다 업데이트 된다 변화(Update),
Dependency Array(의존성 배열)이용하여 감지 하고 싶은 값(count)만 업데이트 할 수 있다.변화(Update),
Lifecycle.js 컴포넌트에서 위 그림과 같이 useEffect 안에 return 함수로 컴포넌트를 제거할 수 있다.
(UnMount)
성능 최적화(useMemo)
성능을 최적화하기 위해 계산된 값을 메모이제이션하는 훅
ex) App.js(실습프로젝트와는 별개,일반일기장)
Dependency Array(의존성 배열) data.length(데이터 길이)가 바뀌면 getDiaryAnalysis 계산부분이 진행된다.
*useMemo 사용시 함수가 아닌 값으로 반환된다.
성능 최적화(React.Memo)
컴포넌트를 메모이제이션하여 불필요한 리렌더링을 방지하는 고차 컴포넌트
ex) DiaryList.js 컴포넌트
DiaryList.js 컴포넌트에서 추가로 ControlMenu 컴포넌트를 만들어 리렌더링 방지하는 React.memo 적용한다.
DiaryList.js 컴포넌트에서 랜더링 될때 ControlMenu컴포넌트는 React.memo 되어 props 바뀌지않는 이상 ControlMenu 컴포넌트는 리랜더링 되지 않는다.
성능 최적화(useCallback)
함수를 메모이제이션하여 불필요한 리렌더링을 방지하는 훅
ex) DiaryEditor.js 컴포넌트 일부
DiaryEditor.js 컴포넌트에서 handleClickEmote 함수에 useCallback 사용하여 리랜더링 방지
DiaryEditor.js 컴포넌트 랜더링 부분을 보면 EmotionItem 컴포넌트 onClick 에 props로 handleClickeEmote 함수를 실행한다.
handleClickeEmote 함수에는 Dependency Array(의존성 배열) 부분에 [] 빈배열이므로 첫 클릭후 리랜더리링이 되지않는다.
* handleClickeEmote 함수에 상태값인 emotion이 인자로 들어가는데 조금더 살펴보니 EmotionItem.js 컴포넌트에서 onClick 함수가 emotion_id를 인자로 호출하도록 되어 있다.
* handleClickeEmote 함수에 emotion 인자로 들어노는 부분이 정확히 이해는 안가 GPT를 이용하여 조금더 살펴 보았다.
화면 표출
상태 관리 분리(useReducer)
상태 로직을 컴포넌트에서 분리하여 더 복잡한 상태 관리를 할 수 있게 해주는 훅
ex) App.js 일부
reducer 상태와 액션을 인수로 받아 새로운 상태를 반환하는 함수
state : 상태변화 직전의 값
action : 어떤 상태 변화를 일으켜야 되는지의 정보들이 담긴 객체
* action 객체는 최소 type속성을 가져야 한다.
dispatch(상태 업데이트 함수) : type 속성값으로, reducer함수에 있는 action.type 값이랑 맵핑하여 상태값 반환.
* dispatch 함수를 사용하여 다양한 액션(action)을 처리하고, 그에 따라 상태를 업데이트(reducer) 한다.
컴포넌트 트리에 데이터 공급(Context)
전역적으로 데이터를 관리하고 전달할 수 있게 해주는 API
ex) 일반일기장 전체 도식화(실습프로젝트와별개, context 적용전/적용후)
Context 적용전 위 그림과 같이 DiaryItem.js 컴포넌트까지 함수를 prop로 전달하기 위해 사용하지도 않는 DiaryList.js 컴포넌트를 통해 거쳐가야했다.(onRemove,onEdit)
Context를 적용하면 App에 구현한 데이터 및 함수를 전역으로 배치시켜 각 컴포넌트에 바로 할당할 수 있다.
ex) App.js , DiaryEditor.js 컴포넌트 일부
App.js 컴포넌트에서 Context 생성
랜더링시 Context.Provider 이용하여 전역으로 전달하는 값을 넣는다.
DiaryjEditor.js 컴포넌트에서 다른 컴포넌트 안거치고 Context에 있는 데이터(DiaryDispatchContext)바로 받아오기
페이지 라우팅(React Router)
SPA(Single Page Application)에서 페이지 간 이동을 관리할 수 있게 해주는 라이브러리입니다.
ex) App.js , Diary.js 일부
BrowserRouter를 사용하여 라우터 설정
Routes 와 Route를 사용하여 라우팅을 설정한다.
Route는 url 경로와 접근한때 랜더링될 컴포넌트를 정의 한다.
get('속성명')으로 url값을 가져올수 있다.
반대로 상태를 업데이트(setSearchParms) 하여 url에 객체 값을 넣을 수 있다.
이미지와 같이 naviate 생성한다.
navigate('이동할 경로명',{replace : true})
* {replace : true} 뒤로가기 방지
* 경로명에 -1 넣을시 바로 전 페이지로 이동
작업URL
https://sungman-react-emotiondiary.web.app/
감정 일기장
하루하루 일기 쓰세요!!
sungman-react-emotiondiary.web.app
Github 링크
https://github.com/josungman/Programmer-s_Web_App_Dev_Course/tree/main/week9/emotiondiary
Programmer-s_Web_App_Dev_Course/week9/emotiondiary at main · josungman/Programmer-s_Web_App_Dev_Course
클라우딩 어플리케이션 엔지니어링 코스. Contribute to josungman/Programmer-s_Web_App_Dev_Course development by creating an account on GitHub.
github.com
느낀점
기록이 서툴러도, 기록을 통해 조금씩 나만의 것을 만들어가야겠다.
'클라우딩 어플리케이션 엔지니어링 TIL > 9주차' 카테고리의 다른 글
[파트6] 리액트 빌드 및 배포 과정 (0) | 2024.06.16 |
---|---|
[파트6] 리액트 실습 개발자 도구 활용 (0) | 2024.06.16 |