React + Unstated-next로 간단한 플젝 만드기
React
+ Unstated-next
로 간단한 플젝 만드기 🚀
React 프로젝트 초기 설정 🛠
create-react-app
사용
Webpack 설정 vs create-react-app
create-react-app의 webpack
- 참고 : https://medium.com/wasd/create-react-app-%EC%9D%98-webpack-config-js-%EB%93%A4%EC%97%AC%EB%8B%A4%EB%B3%B4%EA%B8%B0-78e40bf37313
react-scripts eject
: 숨겨진 설정 파일을 추출하는 명령어config
,scripts
폴더 나타나고package.json
파일에 모든dependency
와babel
,jest
설정 코드가 드러남- cra와 eject 쓰는 이유
- 참고 : https://medium.com/@jsh901220/create-react-app%EC%97%90%EC%84%9C-eject%EC%82%AC%EC%9A%A9%EC%95%88%ED%95%98%EA%B8%B0-customize-cra-react-app-rewired-10a83522ace0
첫 번째 시도
1
npx create-react-app login-poc --typescript
--typescript
를 붙였음에도 typescript 설치를 못하고 js로 설치됨
- 두 번째 시도
1
npx create-react-app login-poc --template typescript
cra 공식 깃헙에서도
--template typescript
가 공식 타입스크립트 템플릿이라고 함
1
2
3
4
5npx create-react-app my-app --template typescript
# or
yarn create react-app my-app --template typescript
- ❗ 예전에는
--typescript
를 붙이면 됐는데--template
형식으로 바꼈나보다!
eslint 설정 🛠
eslint 설치
@typescript-eslint/parser 설치 : eslint가 typescript를 lint 할 수 있도록 해줌
@typescript-eslint/eslint-plugin : typescript에 구체화된 eslint rule을 포함한 플러그인 설치
1
yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev
devDependencies
에 추가하고 싶으면 뒤에--dev
oryarn add -D
⁉️ 이슈
tsconfig
의 jsx
부분에서 이슈가 있었는데
Specify JSX code generation: 'preserve', 'react', 'react-jsx', 'react-jsxdev' or'react-native'. Requires TypeScript version 2.2 or later.
VScode의 이슈였당..
This is because VSCode’s Typescript version is not using the newest babel features that create-react-app uses by default.
command + shift + p 에서
typescript: select typescript version
에서 useWorkspace version 선택
Prettier 설정 🛠
- 참고: https://flamingotiger.github.io/javascript/eslint-setup/
- prettierrc 설정 후 IDE에서도 설정
- vscode인 경우 settings.json
환경 변수 설정 🛠
참고 : https://create-react-app.dev/docs/adding-custom-environment-variables/
환경변수
참고:
환경변수 : 환경(특정 process)의 조건을 정하는 것
Node.js 기반 :
process.env[key]
형태
ex)
process.env.NODE_ENV
크로스 플랫폼 환경변수 설정
create-react-app
기반
참고
root 폴더에
.env
파일 추가
파일 안에
REACT_APP_변수명
으로 변수 생성해서 사용
- 변수명은 무조건
REACT_APP_
으로 시작해야 함
- 변수명은 무조건
사용예시
1
2
3<div>
{process.env.REACT_APP_변수명}
</div>
development
환경일 때와production
환경일 때 다른 api 주소를 가지도록 하려면
- root 폴더에
.env.dev
혹은.env.development
= 개발 환경.env.prod
혹은.env.production
= 배포 환경
- 이 외에도
.env.test
,.env.local
등이 있음
- root 폴더에
package.json
의scripts
에 따라 불러오는.env
파일 결정. 뒤로 갈 수록 우선순위 낮아짐npm start
:.env.development.local
,.env.development
,.env.local
,.env
npm run build
:.env.production.local
,.env.production
,env.local
,.env
npm test
:.env.test.local
,.env.test
,.env
Unstated-next 설치 🛠
yarn add unstated-next
- 튜토리얼 : https://css-tricks.com/managing-state-in-react-using-unstated-next/
Apollo/client 설치 🛠
- ApolloClient를 생성하려면 uri가 필요한데, 고정적인 값이 아닌 환경에 따라 다른 값이 들어가야함
- cra에서 환경변수를 설정하는 방법
- Adding Custom Environment Variables 참고
Axios 설치 🛠
apollo/client
를 위해 설정한 환경변수가 root에.env.development
이런 식으로 되어있는데,axios
의base url
은 apollo거랑은 다름- .env.development에 이렇게 환경변수 이름을 다르게 줌
1
2REACT_APP_APOLLO_BASE_URL='https://url주소'
REACT_APP_AXIOS_BASE_URL='https://url 주소'
- .env.development에 이렇게 환경변수 이름을 다르게 줌
- 유연한 axios 인스턴스 만들기
- https://laravel-news.com/building-flexible-axios-clients
- typescript class의 private 변수는?
- https://hyunseob.github.io/2016/10/17/typescript-class/
- 클래스 내부에서만 접근할 수 있으며 내부 인터페이스를 구성할 때 쓰이는 변수
- https://hyunseob.github.io/2016/10/17/typescript-class/
Router 설정 🛠
create-react-app
에는 routing을 위한 로직이 없기 때문에react router
를 따로 설치해줘야 함routing : 다른 주소에 따라 다른 뷰를 보여주는 것
참고 : https://jeonghwan-kim.github.io/dev/2019/07/08/react-router-ts.html
yarn add react-router-dom
yarn add -D @types/react-router-dom
: react-router-dom의 type 정의 라이브러리
<BrowserRouter />
: HTML5 히스토리 API를 사용하여 주소를 관리하는 라우터<Switch />
: 하위에중 하나를 선택 <Route />
: 요청 경로와 렌더링할 컴포넌트를 설정<Redirect />
: 요청 경로를 다른 경로롤 리다이렉션
page
>index.ts
에서Home
컴포넌트 lazy 로딩
lazy loading 왜?
React
의lazy
는 코드분할 을 하도록 해주는데, 코드 분할을 하면 사용자가 필요로 하지 않는 코드를 불러오지 않게 해주어서 앱의 초기 로딩에 필요한 비용을 줄여준다.
참고
React.lazy
+Suspense
React.lazy
- 컴포넌트를 렌더링하는 시점에서 비동기적으로 로딩할 수 있게 해주는 util 함수
- 동적 import를 사용해서 컴포넌트를 렌더링
- React 컴포넌트를 포함하며 default export를 가진 모듈로 결정되는 Promise로 반환
- lazy 컴포넌트는 Suspense 컴포넌트 하위에서 렌더링되어야 함.
Suspense
리액트 내장 컴포넌트
코드 분할 된 컴포넌트(lazy 컴포넌트)를 로딩하도록 해주고 로딩이 끝나지 않았을 때 보여줄 UI(예비 컨텐츠)를 설정할 수 있음
1
<Suspense fallback={<div>loading...</div>}
fallback
props를 통해 로딩 중에 보여 줄 JSX를 지정할 수 있음
⁉️ 이슈
App.tsx
에서만들어주고 routes를 map으로 돌리는 과정에서 key 값을 uuid
라는 라이브러리를 사용해서 유니크한 값을 사용하려고 했는데 에러 발생
‘uuid’ should be listed in the project’s dependencies. Run ‘npm i -S uuid’ to add it import/no-extraneous-dependencies
- @types/uuid 만 설치해주면 되는 줄 알았는데
uuid
도 설치했어야했다. @types
는 자바스크립트 라이브러리를 타입스크립트 추론이 가능하도록 도와주는 보조 라이브러리
- @types/uuid 만 설치해주면 되는 줄 알았는데
Unstated-Next 구조 잡기 🛠
참고
최상위인
App.tsx
에서container
를 내려주는 것이 아니라 해당container
가 필요한 컴포넌트에서만 받을 수있도록 컴포넌트를 감싸는 상위 컴포넌트에서Provider
로 내려주고container
값이 필요한 컴포넌트에서useContainer
로 받아와서 상태 값을 사용하도록 만들었다.
Node-sass 설치 🛠
⁉️ 이슈
Error: Node Sass version 5.0.0 is incompatible with ^4.0.0
- https://stackoverflow.com/questions/64625050/error-node-sass-version-5-0-0-is-incompatible-with-4-0-0
CRA uses a fixed version,
yarn add node-sass@4.14.1
아직 cra에서 최신 버전의 node-sass를 지원하지 않으니 4.14.1버전으로 설치
etc 📝
Promise.allSettled
는 뭐지?- 기존에 구현되어 있던 로그인 기능에
Promise.allSettled
라는 메소드가 보여 궁금해졌다.Promise.all
만 알고있었는데.. - 참고
Promise.all()
- 인자로 받은 Promise 객체들이 하나라도 실패하면 에러로 넘어가고 Promise의 결과들은 무시된다.
Promise.allSettled()
- 인자로 iterable 객체(주로 배열)를 받고 객체의 요소들은 모두 Promise 객체
- 성공한 Promise는
{status: 'fulfilled', value: 값}
이 반환되고 실패한 Promise는{status: 'rejected', reason: 실패한 이유}
를 반환해준다. - 하나라도 실패해도 에러로 넘어가지 않고 모든 Promise들이 실행되어 결과를 받을 수 있다.
- 반환된
status
에 따라 처리해줄 수 있음
- 기존에 구현되어 있던 로그인 기능에
no-return-await
- 기존에
return await
형식으로 사용하는 부분이 많았는데 eslint에서 에러로 던져줬다. - https://eslint.org/docs/rules/no-return-await
- 기존에