치춘짱베리굿나이스
[프리온보딩] 220510 강의 메모 02 (날씨앱 + 팁) 본문
날씨 앱
서론
- 자기 코드에 자만심갖거나 쪽팔려하지 말자 ⇒ 발전이 없다
- 공식문서 신경 많이 쓰기
- 린터는 절대 끄지마세요
날씨앱 만들기
키값 보관하기 - 환경변수
REACT_APP_[변수명]=[변수값]
REACT_APP_API_KEY=12345678
- 키값 털리면 API 리밋에 걸리거나 돈이 마구 나갈 위험이 있음
- 깃허브에 올리지 않도록 하기 위해
.env
파일 등에 넣는다 - 위의 형식으로
.env
파일을 저장하면process.env.REACT_APP_API_KEY
와 같은 식으로 환경변수를 사용할 수 있다 - CRA로 생성한 프로젝트는 변수명 앞에 접두사로
REACT_APP_
을 붙여줘야 인식함
NavLink 사용하여 내비게이션 바에 링크 달기
...
<nav className={...}>
<ul>
<li>
<NavLink
to='favorites'
className={({isActive}) => cx({ [styles.isActive]: isActive })}
>
Favorites
</NavLink>
</li>
<li>
<NavLink
to='movies'
className={({isActive}) => cx({ [styles.isActive]: isActive })}
>
Movies
</NavLink>
</li>
</ul>
</nav>
...
ul
바로 아래에li
를 넣어주자
React-Router-Dom에서 Link와 NavLink의 차이
Link
태그는a
와 비슷하다- 특정 링크를 정의하면 해당 링크로 이동할 수 있도록 도와줌
NavLink
는Link
와 유사하나,className
에isActive
를 넣을 수 있다- 현재 어느 페이지에 위치해있는지 알 수 있기 때문에, 그에 따라서 스타일링을 다르게 할 수 있다
- 내비게이션 바 등에 유용함 (볼드처리, 색상처리 등)
- 두 개의 차이는
isActive
의 유무
Route 설정
return (
<div className={...}>
<GNB /> { /* 위에서 만든 내비게이션 바: Global Navigation Bar */ }
<div className={...}>
<Routes>
<Route path='/' element={<Movies />} />
<Route path='movies' element={<Movies />} />
<Route path='favorites' element={<Favorites />} />
<Route path=':index' element={<Favorites />} />
</Route>
<Route path='*' element={<div>404</div>} />
</Routes>
</div>
</div>
)
- 루트경로와
/movies
에서는Movies
컴포넌트를 렌더링 /favorites
페이지와/favorites/1
,/favorites/2
와 같은 인덱스가 붙으면Favorites
페이지를 렌더링- 최상단에 내비게이션 바 배치
- 그 외의 모든 링크에서는 (
*
) 404 출력
useParams
<Route path=':index' element={<Favorites />} />
// Favorites 컴포넌트
...
const { index } = useParams<{ index: number }>();
- react router에서 지원하는 hook으로,
Route
에서 설정해준 인자값을 링크로부터 가져올 수 있게 해준다
axios로 데이터 받아오는 함수 만들기
export const getDataApi = (params: Params) => {
axios.get<IData>(process.env.REACT_APP_API_URL, {
params: {
...params,
apiKey: process.env.REACT_APP_API_KEY
},
})
- data fetch 형식은
axios.get
,axios.post
이런 식으로 하기 - 인자로 넘겨줄 값들은 객체로 보내기 (쿼리스트링 x)
setInterval, clearInterval
let interval: NodeJS.Timeout; // 컴포넌트의 바깥
// 컴포넌트의 안
...
useMount(() => {
interval = setInterval(() => {
getDataApi({
value1: 'aaa',
value2: 'bbb',
}).then((res) => {
setData(res.data);
});
), 3000); // 3초
}); // 컴포넌트 마운트될 때, useEffect 최초실행과 같음
- 특정 함수를 특정 시간 간격마다 실행시킬 수 있다
- 단, interval 해제를 안해줄 경우
setInterval
을 사용하는 컴포넌트가 언마운트되고 다른 컴포넌트로 교체되고도 함수가 계속 실행되며, 그 상태에서 컴포넌트로 돌아올 경우setInterval
이 중첩돼서 지정한 시간마다 함수가 두번 실행되는 불상사가 발생한다
useUnmount(() => {
clearInterval(interval);
}); // 컴포넌트 언마운트될 때, useEffect 반환할때와 같음
- 컴포넌트 언마운트될 때 꼭
clearInterval
해주자 setInterval
할 때 반환값을 받아다가 저장해놔야clearInterval
이 가능하다
setTimeout, clearTimeout
interval = setTimeout(() => {
console.log('hello');
}, 200); // 0.2초
- 특정 함수가 지정한 시간이 흐른 이후에 실행되도록 한다 (딜레이를 준다)
useUnmount(() => {
clearTimeout(interval);
});
- 마찬가지로 언마운트 시에
clearTimeout
을 사용해야 예상치못한 오류가 발생하지 않는다 - 시간이 흐르는 도중 컴포넌트가 언마운트될 경우 동작이 이상해질 수 있음
- 이걸 일일히 정의하는 것도 귀찮으니 hook으로 뭉쳐놓으면 쉽게 사용할 수 있다
useNavigate
useHistory
였었는데 react router 6부터useNavigate
로 바뀜- 특정 컴포넌트의 함수 내에서 다른 컴포넌트로 이동할 때 종종 사용됨
navigate(0)
은 해당 페이지 새로고침
타입스크립트 타입적기 어려울때
타입을 알고 싶은 함수나 이벤트 등 마우스 올리면 타입이 뜸
recoil 팁
const testValue = useRecoilValue(TestState);
const setTestValue = useSetRecoilState(TestState);
const [testValue, setTestValue] = useRecoilState(TestState);
const resetTest = useResetRecoilValue(TestState);
- recoil은 주로 이 네 가지 값이 사용된다
useResetRecoilValue
는 처음에atom
선언할 때 넣어주었던 초기값으로 reset- 이걸 다양하게 쓰는 것보다 그냥 커스텀 훅으로 뭉쳐서
state
,setState()
,resetState
만 받는 게 낫다 - 한 페이지 안에서 (한정된 공간 안에서 = 한 가족 컴포넌트 안에서) 쓰는 것을 권장
- 정말 전역으로 사용하는 것을 권장하지 않음
selector
는get
메서드,set
메서드를 정의하여 특정 값들을 섞어서 가져올 수 있다selector
나family
등의 기타 함수들을 사용하는 건 매우 복잡해지고, recoil 자체가 알파 버전이라 사용법과 규칙이 계속 바뀐다- 차라리
selector
까진 쓸만한데,family
부턴 답없다 - recoil의 장점은 간단한 작업을 할 때 드러난다
atom
만 사용하여state
관리하듯이 사용하는것만을 추천함 (간단하므로)
- 차라리
atom
의 키 값은 절대로 다른 atom의 키값과 겹치지 않도록 주의
배열 초기화할 때 안쓰는 값 버리기
let [, a, b] = [1, 2, 3];
let [,, c] = [1, 2, 3];
- 배열 초기화 시 특정 값이 필요 없으면 변수명을 적지 않는 방식으로 값을 버릴 수 있다
usePrevious (react-use)
const prev = usePrevious(next);
console.log(`${prev} to ${next}`);
usePrevious
훅은 인자로 받은 상태값의 직전 값을 보존한다- 상태가 어떻게 변화했는지 알고 싶을 때 쓰면 좋다
if문 깔끔하게 쓰기
if (조건문)
foo();
if (!조건문) return;
foo();
- 가급적 조건문 안에 return을 넣도록 짜면 들여쓰기 없이 더 깔끔해진다
컴포넌트에 취소선 긋기
.class {
position: relative;
...
&::after { // 애니메이션 이전
position: absolute;
top: 50%;
right: 100%;
bottom: auto;
left: 0; // mixin 쓰면 더 깔끔
content: '';
border-bottom: 1px solid colors.$COLOR;
transition: 500ms; // 원하는 시간 적기
}
}
.crossline { // 애니메이션 이후
.class {
&::after {
right: 0;
}
}
}
after
선택자를 사용해서 취소선을 그을 수 있다- 우측 좌표를 조정해서 우측부터 그이는 식의 연출도 가능하다
css transition에 delay 주기
transition: 0.2s;
transition-delay: 0.5s;
- 이런 걸 많이 알고 있을 수록 코드가 많이 간단해진다
- 눈에 보이는 것들은 어지간하면 css로 해결하는 것이 좋다
Suspense
promise
만 가지고도 쉽게 로딩 화면, 에러 처리 등을 할 수 있다
redux와 redux-toolkit
- redux만 가지고선 함수 하나 짜는데 코드나 파일을 많이 필요로 했지만, redux-toolkit으로 쉽고 간단하게 가능하다
- redux-saga는 꽤 legacy 가 되었다
- 모듈화된 개발이 가능하다
- 하늘과 땅 차이
react-query
- 상당히 괜찮지만, 처음 배우기는 좀 어렵다
상대경로 vs 절대경로
import TestComponent from '../../TestComponent';
import TestComponent from 'components/TestComponent';
- 상대경로보다 절대경로가 나은것이, 파일구조가 조금만 바뀌면 파일 불러오기가 다 꼬이기 때문에 왠만하면 바뀌지 않는 + 보기에도 직관적인 절대경로가 낫다
StrictMode 해제하지 말 것
- 렌더링이 두번 되면 두번 되는 이유가 있다
- 렌더링이 되는 이유: 상태값의 변화, 상위 컴포넌트의 변화, 하위 컴포넌트의 변화
- 어지간하면
React.StrictMode
해제하지 않는 것이 좋다
린터가 특정 오류를 안잡아줄 때
"extends": ["airbnb", "airbnb/hooks", "react-app", "prettier", "plugin:react/recommended"],
- 린터 플러그인 로딩 순서 오류로 이전에 불러온 라이브러리가 덮어씌워졌을 가능성이 있다
세미콜론은 자유
- 세미콜론을 붙여도 되고 안붙여도 됩니다
150줄 제한은 어지간하면 지키자
- 150줄이 넘어갈 수록 컴포넌트 분리를 해야할 확률이 높다
- 관심사가 분산되어 보기싫은 코드가 될 가능성이 큼
TDD
- 백엔드는 TDD의 중요성이 크지만, 프론트엔드는 대부분의 버그가 렌더링 단에서 일어나기 때문에 컴포넌트 유닛 테스트가 아닌 이상 그렇게 영향이 없다
'프로젝트 > 원티드 프리온보딩' 카테고리의 다른 글
[프리온보딩] 220515 강의 메모 01 (코드리뷰) (0) | 2022.05.17 |
---|---|
[프리온보딩] 220516 그룹과제 #2 시작 (0) | 2022.05.17 |
[프리온보딩] 220510 강의 메모 01 (간단 코드리뷰) (0) | 2022.05.16 |
[프리온보딩] 220515 개인과제 #1 종료 (0) | 2022.05.16 |
[프리온보딩] 220514 개인과제 #1 완성 및 배포 (0) | 2022.05.15 |
Comments