치춘짱베리굿나이스

[프리온보딩] 220510 강의 메모 02 (날씨앱 + 팁) 본문

프로젝트/원티드 프리온보딩

[프리온보딩] 220510 강의 메모 02 (날씨앱 + 팁)

치춘 2022. 5. 17. 01:14

날씨 앱

서론

  • 자기 코드에 자만심갖거나 쪽팔려하지 말자 ⇒ 발전이 없다
  • 공식문서 신경 많이 쓰기
  • 린터는 절대 끄지마세요

날씨앱 만들기

키값 보관하기 - 환경변수

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와 비슷하다
    • 특정 링크를 정의하면 해당 링크로 이동할 수 있도록 도와줌
  • NavLinkLink와 유사하나, classNameisActive를 넣을 수 있다
    • 현재 어느 페이지에 위치해있는지 알 수 있기 때문에, 그에 따라서 스타일링을 다르게 할 수 있다
    • 내비게이션 바 등에 유용함 (볼드처리, 색상처리 등)
  • 두 개의 차이는 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>
)
  1. 루트경로와 /movies 에서는 Movies 컴포넌트를 렌더링
  2. /favorites 페이지와 /favorites/1, /favorites/2 와 같은 인덱스가 붙으면 Favorites 페이지를 렌더링
  3. 최상단에 내비게이션 바 배치
  4. 그 외의 모든 링크에서는 (*) 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만 받는 게 낫다
  • 한 페이지 안에서 (한정된 공간 안에서 = 한 가족 컴포넌트 안에서) 쓰는 것을 권장
    • 정말 전역으로 사용하는 것을 권장하지 않음
  • selectorget 메서드, set 메서드를 정의하여 특정 값들을 섞어서 가져올 수 있다
  • selectorfamily 등의 기타 함수들을 사용하는 건 매우 복잡해지고, 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의 중요성이 크지만, 프론트엔드는 대부분의 버그가 렌더링 단에서 일어나기 때문에 컴포넌트 유닛 테스트가 아닌 이상 그렇게 영향이 없다
Comments