React 공부(모던 리액트 Deep Dive, 리액트 공식 문서)
useState
의 인자로state
의 초기값을 전달할 수 있다.- 만약에 인자로 콜백 함수를 전달하면(e.g.
useState(() => { return 1 }
) 최초 마운트 시에만 실행되며, 해당 콜백 함수의 리턴 값으로state
가 초기화된다. useState
에 전달하는 함수는 순수해야 하고(순수 함수여야 하고), 인수를 받지 않아야 하며, 반드시 어떤 값을 반환해야 한다. 해당 반환 값이state
가 된다.setState
함수는 다음 번state
값을 전달할 수 있다. 다만,setState(age + 1)
setState(age + 1)
setState(age + 1)
이렇게 같은 함수를 세 번 연속으로 실행하면 값은 1만 증가된다. 왜냐하면,state
는 한 번의 리렌더링 분기에 한 번만 업데이트 되며, 이후에 변화 명령은 무시되기 때문이다.state
는 스냅샷처럼 동작한다.- 만약에 실제로
age
를 세 번 1씩 증가시키고 있다면setState(() => age + 1)
처럼 함수를 콜백 형태로 전달하면 된다. 콜백으로 전달된 해당 함수를 업데이터 함수라고 한다. useState
의setState
함수는 이전state
와 현재state
를Object.is
로 비교해서 변경 사항이 없다면 리렌더링을 건너뛴다. 그리고, 이 경우 참조값 데이터는 얕은 비교를 하며, 객체 내부의 값이obj.value = 2
처럼 접근하여 변경했다면 원본 객체는 참조를 유지하기 때문에 리렌더링되지 않는다.{...obj, value = 2}
처럼 객체를 새로 만들어 값을 할당해야 한다.useEffect
는 컴포넌트가 렌더링된 후 어떠한 부수 효과를 실행하고 싶을 때 사용하는 훅이다.- 의존성 배열에
state
나props
를 전달하면 해당 값이 변경될 때에만 첫 번째 인자인 콜백 함수가 실행된다. 빈 배열을 전달하면 컴포넌트가 최초 마운트될 때에만 실행되고, 아예 두번째 인자로 값을 전달하지 않으면 모든 리렌더링에서 콜백 함수가 실행된다. useEffect
의 첫 번째 인자로 전달하는 콜백 함수에는 이름을 붙일 수 있다. 이름을 붙이고 나면 여러useEffect
구문이 실행됐을 때 어떤 실행 함수에서 어떤 식으로 동작하는지(문제가 생겼다면 이유가 뭔지) 추적하기에 수월하다.useEffect
의 콜백 함수는 렌더링 작업 이후에 실행되기 때문에 렌더링 성능에는 영향이 적지만, 자바스크립트 실행 성능에 영향을 미치기 때문에, 가능한 작게 유지하는 게 유리하다. 또한, 하나의useEffect
콜백 함수의 사이즈가 너무 커지면 그 안에서 발생될 사이드 이펙트를 예상하고 관리하기 어려워진다. 이런 문제를 예방하기 위해,useEffect
의 콜백 함수는 간결하게 유지해야 한다- 만약에 의존성 배열에 여러 변수를 담아야 한다면, 최대한
useCallback
과useMemo
등으로 사전에 정제한 내용만 담아두는 것이 좋다. 그러면useEffect
의 실행 시점이 조금 더 명확해진다. useEffect
의 인자인 콜백 함수로 비동기 함수를 전달받을 수 있지만, 실행 순서의 보장이 어려워state
가 경쟁 상태(Race Condition)에 빠질 수 있고, Clean up 함수의 실행 순서도 보장하기 어렵기 때문에, 개발자의 편의를 위해 비동기 함수를 인자로 받는 걸 지양하는 게 좋다.useEffect
의 Clean up 함수는useEffect
콜백 함수의 구문이 다음 번에 다시 호출될 때 이전state
값으로 실행된다. 즉, 이전state
로 콜백 함수 실행 -> 실행 종료 -> 이전state
로 클린업 함수 실행 -> 다음state
로 콜백 함수 실행 -> 실행 종료 순서가 반복되는 것이다. 만약에 컴포넌트가 DOM에서 제거된 경우에도 정리 함수가 실행된다.- 공식 문서 상
useEffect
의 정의는 '외부 시스템과 컴포넌트를 동기화하는 것'이다. 그리고, 여기서의 '외부 시스템'이란 'React에 의해 컨트롤되지 않는 모든 코드'를 의미한다. 즉, 컴포넌트의 리렌더링이 완료된 후, 상태 변경으로 인한 자동 실행이 되지 않은 곳에 변화를 주는(Effect를 만들어내는) 훅이라고 이해할 수 있다.
감정 일기장 만들기
- 일기 조회, 생성, 삭제, 수정 기능이 있는 감정 일기장 완성
- 오늘 공부하면서 배운 내용
- 폴더 구조를 짤 때에도 프로젝트 전체의 형태와 구조가 한 눈에 들어오도록 짜는 게 중요하다.
- 모든 페이지에서 공통으로 활용되는 컴포넌트는
layout
이라는 이름의 폴더로 관리할 수 있다. - 변하지 않는 값을 지니면서 여러 모듈에서 공유해야 하는 변수는
constants
정도의 이름으로 폴더링해서 관리할 수 있다. - 특정 페이지에서만 사용되고, 다른 곳에선 활용될 가능성이 적은 컴포넌트는 아예 해당 페이지의 폴더로 귀속시키는 것도 방법이 될 수 있다.
- 이외에도 다양한 폴더 구조에 대한 고민이 든다. 현업을 하고 계신 다양한 분들의 사례를 잘 찾아보면서 배워가야겠다.
- 기능 동작은 전부 구현했지만, 아직은 좀 더 개선할 여지가 있다고 생각한다. 가장 상위의 상태를 Context로 정의해서 공유했지만, 그 하위부터는 prop으로만 전달하는 것도 살짝 어색한 구조여서 바꾸고 싶고, util 함수나 Custom Hook으로 뺄 수 있는 것들을 정돈하는 작업도 해봐야 할 것 같다. 내일은 이런 작업들을 조금씩 해봐야겠다.
'TIL' 카테고리의 다른 글
241125 TIL (0) | 2024.11.26 |
---|---|
241124 TIL (1) | 2024.11.25 |
241121 TIL (2) | 2024.11.22 |
241120 TIL (2) | 2024.11.21 |
241119 TIL (1) | 2024.11.20 |