- UI의 전체적인 구조를 잡아놓자! -> Layout
- 모든 페이지에 동일한 CSS를 주자! -> Global-Styles
포트폴리오 리뷰
- 별점 주기, 보여주기
- 좋아요, 싫어요 구현
- 우편번호 검색(모달창)
- 주소 및 우편번호 수정
주소 및 우편번호 수정하고 보여주기
- 주소값을 수정할때 초기값을 보여주기 위해서 defaultValue를 사용한다.
- 지금까지는 event.target.value로 입력한 값을 받아왔었는데 입력 받은 주소와 우편번호를
value
속성을 통해 역으로 입력한 값을 보여줄 수도 있다.
- 모달창에서 우편번호를 검색해서 입력하고 저장하는 순간 state에는 저장이 되지만 화면에는 바뀌지 않는다. 보여주기 위해서는 props에 넣고
value
에 넣어주어야 저장한 state 값이 보여진다.
- 상세 주소를 제외한 우편번호, 주소는
readonly
속성을 주고 우편번호 검색을 통해서만 수정할 수 있게 한다.
defaultValue vs value
- value 값을 속성으로 주게 되면 수정할 수 없다.
- defaultValue 값은 초기값을 보여주고 수정이 가능하다. -> 수정하기에서 사용
-
defaultValue는 초기값이고 실제로 입력되는 값은 value이다. 이 말은 입력된 값이 없을때 등록이 되는 기본값이기에 만약 초기값인을 나타내는 defaultValue와 값을 나타내는 value 두 개가 있다면 defaultValue는 무시되고 항상 value가 보여진다.
-
위와 같이 되면 수정하기를 했을 때 defaultValue가 무시되어 나오지 않고 zipcode, address가 state이고 빈 state가 보여지게 된다.
-
위 문제를 해결하기 위해 조건부 렌더링
을 이용한다.
등록/수정 프로세스
- 우편번호 검색(모달)을 통해 우편번호와 주소를 입력하면 zipcode, address의 state에 값이 저장된다.
- 저장된 state가 props로 넘어가 value에 값이 들어가서 우편번호와 주소가 화면에 보여진다.
- 나머지 상세 주소를 입력하고 등록한다.
- 수정하기
- 수정하기 누르면 등록과 수정이 같은 컴포넌트 쓰기 때문에 zipcode, address의 초기값이 빈 문자열인 값들이 props로 넘어가고 value에 다시 들어가게 된다.
- 빈 문자열이면
조건부 렌더링
에 의해 props.data?.fetchBoard.boardAddress?.address
값을 보여준다.
-> 여기서 만약 조건부 렌더링이 아닌 defaultValue로 설정하면 value에 의해 무시되고 빈 문자열인 value 값이 보여진다.
정리
주소, 우편번호의 수정은 수정하기 임에도 불구하고 defaultValue가 없고 defaultValue 값이 value 뒤에 조건부 렌더링으로 붙여주어야 한다.
레이아웃
베너 영역 레이아웃 구조 만드는 이유
- 페이지의 공통적인 부분, 베너영역 메뉴 부분이 각 페이지마다 들어간다.
- 컴포넌트로 분리하는 방법이 있지만, 모든 페이지에 import 되어야 한다는 문제가 있다.
_app.tsx 작동 원리 복습
- 모든 페이지의 설정은 app.tsx에서 하고 각 페이지에서 사용하기 위해서는 props로 넘겨주어야 한다.
props.children
- 레이아웃 만들 때 사용
- 레이아웃? UI의 배치
다양한 레이아웃
- 헤더, 사이드바, 푸터는 고정, 바디만 props.children으로 변경된다.
- props.children에 들어오는 것이 페이지이다. MyApp에서 Component들이 각각의 페이지이고 페이지가 Layout으로 들어간다 Layout으로 들어갈때는 props.children으로 들어간다.
- 모든 페이지들이 MyApp에서 보여지는데 MyApp에서 보여지는 것은 Layout 컴포넌트가 보여진다.
- 페이지가 합쳐질 때 Layout에 들어가서 합쳐지게 되는데 레이아웃은 props.children으로 들어간다
- 레이아웃을 만들고 MyApp에 붙여보자!
레이아웃 구조잡기
- 사이즈가 커지게 되면 각각의 헤더, 베너, 메뉴, 푸터 등을 폴더로 나누게 된다.
레이아웃 폴더구조 분리 및 Hidden 영역 설정
레이아웃 폴더구조 분리
- header, banner, navigation, footer 폴더로 분리시키고 그 안에가 사이즈가 커지면 또 container/presenter로 분리시키면 된다.
모든 페이지에서 레이아웃 주는 것은 해결했지만 특정 페이지에서는 숨겨야할 영역이 있다.
Hidden 영역 설정
페이지 주소에 따라
서 숨길 영역을 정해준다.
- 숨길 영역의 페이지 주소를 router로 주소를 Layout으로 가지고 와서 변수에 담는다.
- 주소가 숨길 영역에 숨길 변수(배열)에 포함되는지를 본다. 포함되면 조건부렌더링을 통해 보여주고 삭제하고 한다.
HIDDEN_HEADERS
에 등록된 페이지는 헤더가 사라진다. 다른 페이지는 정상적으로 작동한다.
ApolloSetting 분리
_app.tsx
파일에서 graphql설정, 아이디 인증 설정 등 MyApp과는 관련 없는 설정 등이 굳이 app.tsx 파일에 있어야 할까?
- 따로 설정파일을 만들어 놓고 import 해서 쓰면 깔끔하게 개선할 필요가 있다.
- 앱을 실행하면 MyApp 파일이 보이고 ApolloSetting이 보이게 된다.
- ApolloSetting 안에 들어가고 페이지 접속하게 되면 ApolloSetting 파일이 보여지게 되는데 props.children은 실제로 ApolloSetting 안의 레이아웃이 보이게 된다.
- 이렇게 분리함으로써 app.tsx는 설정과는 무관하게 되고 모든 설정 기능들을 apollo 파일에 저장할 수 있다.
global 스타일 및 폰트 적용
- 글로벌 스타일은 app.tsx에 적용해줘야 한다.
- emotion에서 Global을 import 시켜 태그로 사용하고 속성값으로 styles를 넣어줘야 하는데,
- 글로벌 스타일은 css로 작성해주어 작성해준 globalStyles를 위의 Global 태그의 속성값 style={} 안에 집어넣어주게 되면 적용 완료된다.
폰트, 이미지 다운로드 과정
- 배포한 사이트를 검색
- 배포한 사이트에 24시간 yarn dev 중인 프론트엔드 컴퓨터(서버)에 html,css,js를 다운로드해서 받아가지고 온다
- 화면에 그려준다. (이미지, 폰트 제외)
- 화면에 그리는 과정에서 (img, url 등)주소를 통해서 필요한 것들을 다운로드해서 가지고 온다.
-> 용량이 크기 때문에 다운로드 받고 화면이 보여지면 느리다. 따라서 먼저 접속해서 html,css,js 받아오고 다음에 소스코드 읽으면서 이미지, 폰트 등을 추가로 받아온다.
이미지를 어떻게 더 빨리 다운로드 받아올 수 있을까?
- 화질을 최대한 보존하고 이미지 사이즈를 줄일 수 있을지
폰트 다운로드 중 문제
- 배포 중인 컴퓨터에 접속해서 폰트를 다운로드 받아서 오는 과정에서 화면에 폰트가 보여지지 않는 문제를 해결해보자
FOIT
- FOIT(Flash Of Invisible Text)
폰트 압축률, 폰트 경량화 버전 소개
- 압축률 높은 폰트 다운받기(.woff)
- Subset-Font(경량화 폰트) 잘 안쓰는 글자 폰트 삭제된 폰트
캐러셀 만들기
소소한 꿀팁
?? vs ||
- 첫 번째 존재하는 변수의 값을 반환하는 연산자
null 병합 연산자(??) : 첫 번째 정의된 값을 반환
or 연산자(||): 첫 번재 정의된 값을 반환
let value = 0
let result = value ?? "정의되지 않은 변수"
console.log(result);
result = value || "falsy한 변수"
console.log(result);
파일명을 index로 하는 이유
- index는 관례로 시작을 의미한다.
- import 시 index는 생략이 가능하기 때문에 첫 페이지는 index로 한다.
route
asPath: 현재 주소
route, pathname: path 주소 + 다이나믹라우팅 폴더 구조가 나온다.
route와 pathname이 전에는 쿼리스트링으로 차이가 있었으나 지금은 똑같다.
prettier-ignore
//prettier-ignore
를 통해 밑으로는 prettier 무시한다.