- 코드 리뷰 챌린지 서비스? 만들기
- 코드 리뷰를 위한 체크리스트 부분을 작업했다.
- 짧지만 현업에 계신 분들과 같이 작업해 보면서 배운 게 참 많았다.
- 프로젝트를 할 때 어떤 순서로 준비하고 진행해나가는지, 처음으로 경험해 봤다.
- 일단 현업에 있는 분들의 대화 자체를 따라가는 게 버겁다 보니 위축되는 게 좀 있다. 내 의견이 있다가도 뭔가 전달했을 때 잘 이해를 못 하면 '내가 뭘 잘못 얘기한 건가?' 싶다. 완전 6년 전 처음 사회생활 시작할 때의 모습이 떠올라서 속상했다.
- 그래도 좋은 자극이 됐다. 개발 지식도 지식이지만, 현업에서 어떤 흐름으로 일 하는지, 주로 사용하는 도구는 무엇인지, 뭐가 일반적인 상식이고 뭐는 아닌지, 하나씩 잘 알아가야겠다.
- 코드 리뷰 요청 시 만들 체크리스트 기능을 만들면서는 아래의 내용들이 허들이 됐다.
- 드롭다운 메뉴를 만들고, 버튼을 누르면 메뉴가 펼쳐졌다가 메뉴 밖 아무 곳이나 눌러도 메뉴가 닫히도록 하고 싶었다. 해당 기능을 만드는 데 여러 시행착오와 어려움을 겪었다.
- 먼저
onBlur
이벤트로 메뉴에 포커스 된 게 아웃되면 닫는 방식을 생각해서 구현이 가능한 건지 많이 찾아봤다. 그런데, 메뉴를 만들 때 사용한ul
-li
태그는 포커스가 안되기 때문에onBlur
이벤트도 발생시키지 못한다는 문제가 있었다. - 찾아보니 HTML 요소에
tabIndex
라는 속성을 주면 포커스가 안 되는 요소도 포커스가 되도록 설정할 수 있다는 걸 알게 됐다.tabIndex
의 원래 용도는 접근성 등을 고려했을 때 키보드-마우스 이벤트로 특정 요소에 접근할 수 있도록 순서대로 포커스 시켜주는 것이다. 예를 들어input
이 여러 개 있는 회원가입 창에서input
에 커서를 두고 tab을 누르면 다음input
위치로 자동으로 이동하는데,Form
요소가 아닌 태그에tabIndex
를 넣어주면 (쉽게 설명해서) 탭을 통해 접근할 수 있는 요소가 되도록 해준다. - 해당 속성을 이용해서, 먼저
ul
과li
요소에tabIndex
를 주고, 드롭다운 활성화 시 포커스를 가져가게 한 다음(useRef
로 생성한ref
변수로focus()
했다)onBlur
시 드롭다운 메뉴가 닫히도록 구현해 봤다. - 그런데, 이렇게 하니까
li
로 만들어둔 드롭다운 메뉴를 클릭했을 때 해당 클릭 이벤트가 처리돼서 다음 이벤트 핸들러를 호출하고 동작을 처리하기도 전에 메뉴가 닫혀버려서 원하는 순서로 이벤트가 발생하지 않는 문제가 생겼다. - 비동기로 처리해 줘서 해결해보려 하다가, 배보다 배꼽이 더 커지는 것 같아 다른 방법을 찾았다.
useEffect
로 컴포넌트가 처음 렌더링될 때document
객체에 이벤트 리스너를 등록해서 드롭 다운을 펼치는 버튼을 제외한 모든 영역의 마우스 클릭 이벤트를 감지했다. 그리고,useEffect
클린업 함수로 컴포넌트 언마운트 시 이벤트 리스너를 떼는 식으로 구현했다.- 이렇게 하면 전역의 상태를 이벤트 리스너가 항상 감지해야 하기 때문에 비싼 비용이 발생하는 방식이라고 생각이 들었다. 하지만, 당장 구현해야 하는 기능이라 더 찾아보지 못하고 일단 만들어두긴 했다. 기회가 되면 같은 상황에서 문제를 해결할 수 있는 방법을 좀 더 찾아보던가 해야겠다.
- 할 일 목록 관리 서비스 만들기
export default
로 외부에 공개한 컴포넌트를 같은 폴더(또는 원하는 폴더 위치)의index.ts
에서export { default as components } from './경로'
로 정의해 주면, 외부에서 공개된 컴포넌트들을 받아와 사용할 때 경로를 간결하게 사용할 수 있다.- 예를 들어,
components
밑에 있는Button.tsx
,Input.tsx
,Menu.tsx
,Toggle.tsx
가 있을 때, 네 개 파일에서 각각 임포트해오려면import
문만 네 줄이다. 그런데,components
폴더 하위에 있는index.ts
파일에 외부 공개된 컴포넌트를 등록해 두면 4개의 컴포넌트들을./components
라는 같은 경로에 가져올 수 있어서 편리하다. - 이번 프로젝트에선 API 요청을
axios
로 해보려고 한다.axios
는 비동기 통신 라이브러리다. Javascript나 브라우저 API가 기본 제공해 주는 도구가 아닌, 별도 설치(npm i axios
)와 불러오기(import axios from 'axios'
)가 필요하다. axios
는fetch
와 유사하게 정해진 인자를 전달 호출해 주면Promise
객체가 값으로 반환된다.fetch
는 첫 번째 인자로 요청을 보낼 URL, 두 번째 인자로method
,header
,body
등의 정보가 들어가는 옵션 객체가 전달된다.axios
는axios.get
또는axios.post
처럼 메서드 형태로 호출할 수 있다. HTTP method가 메서드 명에서 이미 특정되기 때문에 관련 정보는 다시 보내줄 필요가 없다.axios
는 첫 번째 인자로 URL 경로, 두 번째 인자로fetch
의body
에 담던 요청 데이터를 넘긴다. 이때,axios
는 기본적으로 직렬화를 지원하기 때문에JSON.strigify
를 사용할 필요가 없다.axios
는 인스턴스를 만들어서 기본config
설정을 추가해 둘 수 있다.axios
인스턴스는 아래와 같이 만든다.
// Axios 인스턴스 생성 const instance = axios.create({ baseURL: 'https://example.io/api/', // 기본 URL 미리 설정해두고, 이후에 실제 요청 보낼 땐 path 정보만 활용 timeout: 5000, // 5000ms 경과 시점까지 서버의 응답이 없으면 에러 반환 header: { "Content-Type": "application/json", } });
- 만약에 인증/인가가 필요한 접근이고, 토큰 방식으로 인가가 이뤄지며, Access Token을 로컬에서 관리해야 한다고 했을 때, 토큰 정보를 API 요청이 이뤄지는 전역에서 접근 가능하면서, 동시에 어느 정도의 보안으로 감춰두는 노력이 필요할 수 있다. 이럴 때
instance
의header
로 미리 토큰을 정의해 두고, 이후에instance.get
instance.post
처럼 요청을 사용하면 도움이 된다. - 아니면
axios.defualt.headers.commont['Authorization'] =
Bearer ${accessToken}` 과 같은 방식으로 axios 라이브러리를 통해 전역 설정으로 Access Token을 관리할 수도 있다. - 하지만,
axios.default.headers
에 전역으로 등록할 수 있는 토큰 숫자는 한계가 있으며, 또한 프로젝트의 모든 곳에서 사용하는 axios 호출에 설정이 적용되기 때문에 의도치 않은 문제가 발생할 수 있다. 때문에, API 인가 토큰 키를 가지고 있는axios
인스턴스를 별도로 만들어서 정보를 관리하는 것이 조금 더 안전하다.
'TIL' 카테고리의 다른 글
241209 TIL (0) | 2024.12.10 |
---|---|
241208 TIL (1) | 2024.12.09 |
241206 TIL (1) | 2024.12.07 |
241205 TIL (0) | 2024.12.06 |
241204 TIL (1) | 2024.12.05 |