티스토리 뷰
1월 1주차, 원티드 프리온보딩 프론트엔드 챌린지 요약
2024-01-02, 포트폴리오 작성을 위한 리액트 프로젝트 고도화
지역변수와 전역변수
프로그래밍 관점에서 둘을 비교한다면 어떨까?
// var → 함수 안에 지역변수로 선언해도 밖에서 값을 수정할 수 있다. (= 문제 발생률 증가)
function test() {
var a = 'abcd';
}
a = 'qwer'
// const, let → 둘 다 함수 안에서 선언된 지역변수를 밖에서 값을 수정할 수 없으며, const는 값 자체를 수정할 수 없다.
function test() {
const a = 'abcd';
let b = 1234;
}
a = 'qwer'
b = 5678;
전역 상태 관리의 필요성
Container - Presenter 방식
- Lifting state up
- Prop drilling
Container - Presenter 방식은 Container에서 비즈니스 로직을 구현하고, Presenter에서 화면을 출력하는 방식이다. 이전에는 'stateless'를 선호하였기 때문에 이러한 방식을 활용했다.
부모 컴포넌트에서 자식 컴포넌트에 필요한 값을 파라미터로 값을 전달한다. 문제는 5번째 자식 컴포넌트에서만 값을 사용하고 싶다면, 부모 컴포넌트에서 5번째 자식 컴포넌트까지 파라미터로 값을 넘겨야 하여 효율성이 떨어진다.
Flux & Redux
'Redux'의 특징으로 'Flux 패턴'을 적용한다.
MVC 패턴일 경우, 액션은 컨트롤러를 통해서 모델을 거쳐 뷰로 이어지지만, 프로젝트가 커질 경우 모델과 뷰 사이의 복잡도도 커진다.
그러나, Flux 패턴에서는 액션은 'Dispatcher'를 거쳐 'Store'에 값이 저장되며, 이는 뷰에 전달되고 다시 필요 시 액션으로 디스패처로 전달되는 과정을 반복한다.
부모 컴포넌트를 'Provider'로 설정하고, 필요한 값을 'Context'로 받아 사용할 수 있다. 위 처럼 모든 컴포넌트에 파라미터로 값을 넘길 필요가 없다.
'Store' 하나에서 변수를 관리하기 때문에 여러 'Provider'를 선언하지 않아도 되며, 'Thunk', 'saga' 등 Middleware를 통한 비동기 처리가 가능하다. 또한, 'Redux Toolkit'이 나오고 설정이 비교적 수월해졌다.
그러나, 'Redux'의 단점은 초기값을 지정해야 하고, 각 항목에 타입을 설정해야 하며, Provider를 설정하고, Provider 구독이 필요하다는 점이다. 또한, 설정할 것들이 많고, Flux 패턴을 적용하여 효율이 떨어질 수 있다. 최근 새 프로젝트에서는 애자일이 일반화되면서 잘 사용되지 않고 있다.
Context API (teature/context_api)
'State'를 'Provide'하는 방식으로, React 내장 기능이기 때문에 별도 라이브러리 설치가 필요하지 않다.
HTTP Request도 Context에서 모두 관리하며, 'context'라는 단어에 맞게 해당 관심사와 관련된 모든 것을 'context'가 관리한다.
프로젝트가 커질수록 'Provide'하는 부분이 커지기 때문에 여러가지 불편함으로 최근에는 잘 사용하지 않고 있다. 이는 'Context API'의 단점으로 비즈니스 로직이 복잡해질 경우 Provider 다수 생성이 필요하며, Provider 1개에 경우에도 설정할 것들이 많다.
Recoil (feature/recoil)
본인이 필요한 값만 'Subscribe'하는 느낌으로 사용할 수 있다. 'useOOO'와 같이 React 개발자들에게 익숙한 문법을 제공한다. 또한, 구조가 간단하여 적용하기 쉽고, 'Concurrent mode'를 지원하며, 렌더링 효율이 좋다.
그러나, 커뮤니티가 크지 않아 정보 습득이 어렵고, 'atom'이 엄청 많아질 수 있는 문제가 발생할 수 있다. 또한, 미들웨어 지원이 없다. 이는, 'HTTP Request' 처리를 별도로 해야하는 문제가 있다.
작성자 본인은 Recoil을 개인 프로젝트에 사용해 전역변수 처리를 하였다.
Zustand (feature/zustand)
다른 것들보다 설정이 제일 간단하다. 그리고 별다른 패턴없이 자유롭게 적용이 가능하며, 'Shallow comparison'을 통한 효율 개선이 가능하다. 그리고 함수형, 클래스형을 모두 지원하며, 패키지 크기가 가장 작다. (번들 크기가 작으면 CDN 접근이 빠르다)
그러나, Recoil과 마찬가지로 커뮤니티가 작아 지원을 얻기 힘들고, 미들웨어가 없다.
React Query
비즈니스 로직들은 대부분 백엔드에서 관리한다. 많은 변수들이 서버에서 불러온 값을 관리하기 위해 사용되기 때문에, 프론트엔드에서 처리하는 경우가 많지 않다. 서버에서 불러온 값들을 클라이언트가 관리하지 않도록 해야 한다.
React Query 최적화
- Fresh
- Stale
- Inactive
staleTime vs cacheTime
'useRestaurantList'를 통해서 확인할 수 있다.
이 때, cacheTime을 설정해도 캐시에 저장하지 않고, 다시 'stale'하는 경우가 발생할 수 있다.
'mount'가 된 시점에 캐시에 저장되도록 만들기 위해서 'refreshOnMount'를 True에서 False로 변경해줘야 한다.
가장 좋은 성능의 툴
위의 모든 툴들을 비교했을 때, 사실상 큰 의미는 없다. 정말 굳이 따져야 한다면, 'Context API'가 성능 부분에서는 가장 좋지 않다. 상태 변경 시 동시에 너무 많은 부분을 're-rendering'하기 때문이다. 그러나, 케이스-바이-케이스이기 때문에 본인 프로젝트에 맞게 사용하면 된다.
만약, 본인이 포트폴리오를 만드는 신입/취준 개발자라면 아무거나 하나 선택해 하나를 진득하게 다루는 게 좋다. '다양한 경험'보다 '깊이 들어갈 수 있는 가능성'을 증명하는 게 중요하기 때문이다. 그렇기 때문에 어떤 라이브러리를 사용하는 지는 크게 상관없다. 다만, '해당 라이브러리를 선택한 이유'를 설명할 줄 알아야 하며, '왜'가 중요하다.
일하고 있는 주니어 개발자라면, 회사에서 사용하고 있는 툴을 더 깊게 공부하는 게 낫다. 새로 나왔거나 사용해보지 못한 툴이 궁금하다면 가벼운 토이 프로젝트를 만들어 보고 블로그에 작성해보자.
꼭 추천해야 한다면, 'React Query'와 'Recoil' 또는 'Zustand'를 추천한다.
'Redux'는 개인 프로젝트에서 사용하기에 부담이 크다. 그리고 'Context API'는 현업에서 잘 사용하지 않는다.
꼭 전역변수를 사용해야 하는가?
아니다. 토스는 'useFunnel'을 사용해 해당 기능이 필요한 컴포넌트에서만 사용될 수 있도록 구현했다.
페이지를 'Routing' 하지 않고 'Component'로 관리한 것이다.
항상 이런 방식을 선택할 수는 없다. 개발 팀의 컨벤션이 중요하며, 컨벤션을 지키는 코드가 가독성에 유리하기 때문이다.
정보 전달
프로젝트를 여러 개 만드는 것보다, 단 하나의 프로젝트라도 좋으니, 그 프로젝트에 집중해 계속해서 리팩토링하는 것이 훨씬 낫다. 이는 어떤 부분을 어떻게 개선할 지 알고 있다는 점을 어필할 수 있으며, 대부분 신입은 '유지보수'를 담당하기 때문에 소스코드를 파악하는 능력이 더 필요하다. 과거에 작성한 코드나 다른 사람이 작성한 코드를 파악하는 능력을 어필할 수 있다.
최적화를 언제 해야 하는지에 대한 답은 병목으로 판단되는 지점, 앞으로 병목이 될 것 같은 지점이지만, 사용자 경험에 영향이 없다면 굳이 할 필요가 없다.
효율적인 컴포넌트화와 디자인 패턴과 아키텍처는 자주 사용되는 아키텍처에 대해서는 수시로 변하며, 어떤 툴이 나오느냐에 따라 변하고 있다.
프론트엔드 아키텍처의 가장 최근 트렌드는? | 요즘IT
처음에는 그냥 기능 구현을 하면 되지만 프로젝트의 크기가 커지다 보면 ‘제대로 정리해두지 않으면 정말 안 될 것 같은 순간’들을 맞이하게 됩니다. 그냥 만들면 쉬운 요구사항도 기존 코드
yozm.wishket.com
MVC 패턴에 대해서 'Model'은 데이터에 해당하고, 'View'는 화면에 해당하며, 'Controller'는 Request와 같이 요청과 응답과 관련된 부분에 해당한다. 폴더를 구성할 때, 파일을 위를 기반으로 구성해보자.
블로그를 자주 관리하고, 글을 자주 작성하기 어려우니, Github의 Flow를 사용해 Commit 관리를 할 수 있다. 이는 관리하는 것처럼 보여질 수 있는 약간의 편법같은 것이니 필요하다면 활용해보자.
수업 자료
GitHub - jasonkang14/react-basics
Contribute to jasonkang14/react-basics development by creating an account on GitHub.
github.com
2024-01-04, 무엇을 테스트 할 것인가?
UI 테스트는 진행하지 않는다. 로그인 화면에서 각 요소의 인풋과 버튼 사이의 거리를 확인하는 것은 의미가 없다. 테스트를 하기 보다 기기에 따라 크기가 달라지는 것을 확인하는 것은 있겠다.
UI 테스트는 스토리북에서 진행할 수 있다.
컴포넌트 렌더링 순서도 무의미하다. JSX는 선언한대로 렌더링되며, 인풋이 버튼 위에 존재하는지는 테스트할 필요가 없다.
이보다, 요구사항의 '사용자 시나리오'에 집중해야 한다.
아이디, 비밀번호를 입력했을 때 버튼이 활성화되고 있는지, 더 중요한 것은 로그인이 성공하는지, 실패하는지처럼 '기능'에 중점을 두고 테스트를 해야 한다.
즉, 테스트를 위한 테스트를 하지 말아야 한다. 사용자가 사용하는 것에 대한 기능에 테스트하는 것을 집중하자.
무엇을 테스트해야 하는가?
로그인이 잘 되는지 확인하기 위해, '이벤트 핸들러가 잘 동작하는지', '버튼이 잘 그려지는지'를 봐야 한다. 만약, 로그인 성공을 테스트하려면 '인풋이 잘 작동하는지', '버튼이 잘 작동하는지', 'HTTP Request도 잘 이루어져 있는지' 확인해야 한다.
이 정도면 통합 테스트이지 않은가? 사실 프론트엔드는 유닛 테스트와 통합 테스트의 경계가 애매하다.
어떻게 테스트할 것인가?
- Given(환경) → When(조건) → Then(결과)
- Then에서 결과를 확인
- True 또는 False 반환
- 에러가 발생한다면 'isError === true'
- 성공한다면, 'isSuccess === true'
- 결과값을 'expectation'과 비교
- 예. expect(<testVariable>).toBe(AAA)
- 테스트는 한 번에 하나씩만!
- 로그인 성공 케이스
- 로그인 실패 케이스
단위테스트
코드의 가장 작은 단위를 테스트
- 각 컴포넌트
- 각 함수
- Jest 자주 사용
로그인을 예로 들면 다음과 같다.
- 아이디와 비밀번호 입력 필드 존재 여부
- 아이디와 비밀번호 입력 필드가 적절한 속성(Type, Name 등) 보유 여부
- 로그인 버튼 존재 여부와 활성화 상태
- 아이디 또는 비밀번호가 없을 때 로그인 버튼을 클릭하면 에러 메시지 표시 여부
- 로그인 함수(예. handleLogin())가 예상대로 동작 여부
위에서 언급한 것처럼 단위 테스트와 통합 테스트의 경계는 모호하다.
통합테스트
여러 컴포넌트나 모듈이 함께 작동하는 경우를 테스트한다.
컴포넌트 간 상호작용을 보고, 단위테스트보다 넓은 범위의 테스트를 진행한다.
로그인을 예로 들면, '아이디와 비밀번호를 입력하고 로그인 버튼을 클릭했을 때, 올바른 요청이 서버로 전송되는지', '서버에서 응답이 오면 적절하게 UI가 업데이트되는지', '로그인이 성공한 후 사용자를 적절한 페이지로 리디렉션하는지'가 해당된다.
프론트엔드에서 단위 테스트와 통합 테스트의 경계가 애매하기 때문에, '모듈'을 어떻게 정의할 것인지, 프론트엔드에서 '기능'을 어떻게 정의할 것인지 생각해봐야 한다.
E2E 테스트
사용자 관점에서 애플리케이션 플로우를 전체적으로 테스트한다.
이는, 사용자의 실제 흐름을 테스트한다.
실제 환경에서 테스트하게 되며, '모든 컴포넌트', '데이터베이스', '네트워크', '사용자 인터페이스'를 테스트할 수 있다.
로그인을 예로 들면, 사용자가 실제 환경과 같은 상황에서 웹 사이트를 방문하여 아이디와 비밀번호를 입력하고, 로그인 버튼을 클릭하는 과정을 시뮬레이션한다.
그러나, 애자일에 부적합하다고 생각되며, 그 이유는 빠른 대응과 수정이 불가능하기 때문이다.
프론트엔드 TDD
가능하다. 디자인 시스템이 갖춰져 있다면 특히 매우 수월하다.
'Atomic component' 조합만 충분히 해도 가능하다. 여기서, 'data-testid', 'data-cy' 등의 설정만 잘 해주면 된다.
그러나, 꼭 해야 하는지에 대해서는 의문이다.
애자일 조직 특성에 맞지 않고, TDD를 해야만 검증이 되는 것은 아니다.
만약, 테스트 코드를 잘못 작성했다면?
제대로 된 검증은 어렵고, 코드 상으로 리뷰만 해야 한다면?
오히려 놓치는 부분이 나타날 수 있기 때문에 TDD를 해야 하는 것에 대해 고민해봐야 한다.
강사 기준으로 TDD는 과대평가가 된 느낌이 없지 않아 있다.
취업 동향 확인 방법
채용 공고를 많이 확인하는 게 가장 좋은 방법이다.
각 기업마다 어떤 것을 요구하는 지 바로 확인할 수 있다. 이 때, 경력에 대해서는 너무 깊게 고민하지 말고, 지원해보는 것도 괜찮다.
'여러가지 활동 > 프리온보딩 프론트엔드 챌린지' 카테고리의 다른 글
React에 대해 (1) | 2024.04.03 |
---|---|
프론트엔드 성능 측정과 코드 최적화 (1) | 2024.01.11 |
12월 프리온보딩 프론트엔드 챌린지 후기 (1) | 2023.12.16 |
프론트엔드의 비즈니스 로직와 React (0) | 2023.12.16 |
SOLID 컴포넌트 (0) | 2023.12.14 |
- Total
- Today
- Yesterday
- node
- 설명회느낌점
- 포스텍애플아카데미
- 그룹인터뷰후기
- 포스텍애플디벨로퍼아카데미
- #포스텍애플디벨로퍼아카데미
- 자바스크립트
- Express
- if(kakao)dev2022
- React
- 싱글톤
- 원티드 프리온보딩 챌린지
- 최종추가합격
- LottieFiles
- 고민한 부분
- DB Error MongooseServerSelectionError
- 조코딩과함께
- PostechAppleDeveloperAcademy
- 코딩테스트 대비
- 깃허브 Merge
- 프론트엔드 챌린지
- 원티드 프리온보딩
- javascript
- 스프링
- Frontend
- Singleton
- Default Branch
- 개발자이력서꿀팁
- 신입개발자가 준비해야 할 것들
- 개발 이력서 지원 팁
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |