
스타일 컴포넌트의 장점? 조건부 스타일링을 하기가 쉽다. className을 사용하면 조건부 스타일링이 까다로움

useState는 상태를 관리할 수 있다! 가장 기본적인 hook이며, 함수 컴포넌트에서 가변적인 상태를 가지게 해준다. 복습: useState로 원시 데이터가 아닌 데이터를 변경해야 할 때는 불변성을 유지해야 한다.
const [state, setState] = useState(initialState);


일반 업데이트와 함수형 업데이트 방식은 어떤 차이가 있을까? 전자에서는 onClick을 했을때 setNumber라는 명령을 3번 내리지만 리액트에서는 그 명령을 하나로 모아서 최종적으로 한번만 실행 시킨다. 후자에서는 3번 하면 각각 그 명령을 한번씩 실행시킨다.
useEffect란? useEffect가 속한 컴포넌트가 mount/unmount 될 때마다 특정 작업을 수행할수 있게 하는 hook이다. useState과 마찬가지로 useEffect 역시 import를 해와야 사용 가능함.


하지만 무한렌더링을 막을 방법은 있다! 방법은 dependency array (의존성 배열)

useEffect의 또 다른 활용: cleanUp
cleanUp이란? 컴포넌트가 화면에서 사라졌을 때 무언가를 실행하고 싶다! 할 때 쓰임

return안에 실행하고픈 것을 넣어주면 됨
*추가로 알아볼 것: strictmode, LifeCycle
Redux는 상태 관리 라이브러리이다.
전역 상태 관리가 뭘까? 기존 react 방식대로라면 props를 통해서 부모에서 자식으로 정보를 전달할 수 있었다. 하지만 그 한계 때문에 여러 문제 발생.. 만약 컴포넌트를 잘게 분리해 놨는데 그 정보들을 받아와서 업데이트해야한다면??? 자식이 부모를 변경해야 할 때도 있는데 ㅜㅜ. 그래서 우리는 전역, 즉 글로벌하게 상태를 저장할 수 있는 곳을 따로 만들고 어떤 컴포넌트던지 쉽게 접근이 가능하게 해줄건데, 이것이 바로 Redux이다.

LocalState (지역상태): 컴포넌트 안에서 useState를 이용해 생성한 상태
GlobalState (전역상태): 중앙화 된 곳에서 state들을 관리 하는곳. store이라는 중앙관리소를 만들어서 이용
Redux 실행 CLI: yarn add redux react-redux

redux: redux와 관련된 모든 코드들을 모아 놓을 폴더
config: redux의 설정과 관련된 파일들을 모아 놓을 폴더
configStore.js: 중앙스테이트 관리소
modules: state의 그룹. (ex. Todo list를 만드는데 필요한 state들이 모두 모여있을 todo.js = module)

Module은 기능의 이름을 따서 파일을 생성한다.
Module의 구성요소로는 initialState와 Reducer가 있다.
초기값은 꼭 객체가 아니어도 되고 배열/원시 데이터도 올 수 있다. 객체에도 여러 변수를 넣어줄 수 있다. Reducer란 변화를 일으키는 함수이다.

redux는 reducer가 있는 store라고 할 수 있다. Store는 상태를 저장하는 장소인데, 우리가 어떤 action을 일으키는 것을 dispatch라고 하는데, reducer가 우리가 action을 일으켰을 때 자동실행되고 그 action에 맞게 데이터를 수정해준다. 즉, store에 있는 데이터를 바꿔주는 역할을 reducer가 한다.
예제:
1. modules 폴더안에 counter라는 리듀서 생성
2. 이 모듈을 store에 연결 시키려면 configStore.js에서 counter 모듈 import
3. rootReducer 부분에 counter 모듈 추가. 연결 완료!
4. store과 module을 잘 연결 했는지 확인하려면 component에서 redux의 store을 조회하면 됨. 이 때 useSelector라는 react-redux의 hook을 사용한다.
5. App.js로 넘어가서 useSelector import해온 다음 사용
useSelector state는 모든 module의 state를 조회할 수 있는 값이다.

useState를 사용했을 때는 위의 방법처럼 setNumber를 사용해 number+1 를 해주었다.
Redux에서는 reducer를 사용한다. 만약 counter.js module에 있는 number에 +1을 하고 싶으면 어떻게 해야 할까? number+1 명령을 만들고, 보내고, reducer에서 명령을 받아서 실행한다. (= reducer에게 변경하라는 명령을 내리면 됨 = action)
전역상태라는 것은 변경값을 어느 컴포넌트에서나 쉽게 접근해서 조회할 수도 있고 그 값을 변경하는 것도 그만큼 쉬워진다.

내가 임금이고, reducer라는 신하한테 "더하기를 수행하라!" 라는 편지를 보냈는데 그 편지가 외국어에 형식 엉망으로 왔다면? 해석을 못함 ㅜㅜ 그래서 반드시 형식에 맞춰서 reducer에게 명령을 해줘야하는데, 이게 바로 action 객체이다.
이 액션객체라는 명령을 보내주기 위해서는 useDispatch()라는 hook을 사용하는데, 이것 역시 react-redux에서 import해와서 사용한다. 함수이기 때문에 괄호를 꼭 붙히고, 그 괄호 안에 액션객체를 넣어준다.
그렇다면 그 다음은 액션객체를 받는 방법! 카운터 코드로 넘어가서 console.log(action) 찍고 App.js를 실행하면 액션객체로 전달해준 값이 찍힌다.


useState에서도 맞는 state가 변경되면 화면이 리렌더링 되듯, redux에 존재하는 state도 값이 변경되면 useSelector를 하고 있는 component도 모두 다시 리렌더링 된다.
MINUS_ONE 버튼을 만드려면? 일단 App.js에서 버튼 온클릭 디스패치 만들고 -> counter.js에서 스위치 문에 케이스 추가
요약:
1. 액션객체란 반드시 type이란 key를 가져야 하는 객체. 또한! reducer로 보낼 명령. 액션객체 type의 value는 대문자로 작성한다 (JS에서 상수는 대문자로 작성함)
2. dispatch란 액션객체를 reducer로 보내는 전달자 함수이다
3. reducer란 dispatch를 통해 전달받은 액션객체를 검사하고, 조건이 일치했을 때 새로운 상태값을 만들어내는 변화를 만들어내는 함수이다
4. dispatch를 사용하기 위해서는 useDispatch라는 hook을 이용해야 한다
Action creator를 사용하게 되면 액션객체를 한 곳에서 관리할 수 있도록 함수와 action value 상수를 이용하게 된다.
원래는 reducer 코드에 initialState와 reducer만 존재했지만 이제는 action creator들이 추가된다. 상수로 값을 주는 action value들이 있고, 그 action value 상수를 이용해서 type을 반환한 함수 들인 action creator가 추가가 된다. App.js를 열어서 action creator들이 사용될 수 있게 import를 해주고 만든 action creator를 호출한다.
그러면 왜 action creator를 사용해야 할까? 자동완성 기능을 보조할 수 있기 때문에 휴먼에러를 방지할 수 있고 유지보수 효율성이 증가하며 코드 가독성이 높아진다.
카운터 프로그램을 사용하는 사용자가 직접 숫자 N을 더하고 뺄지 정할 수 있게 하고 싶다면? 그처럼 reducer에 좀 더 어려운 명령을 내릴때 payload를 사용한다. N을 같이 reducer에 보내야 하는데 이 N이라는 목적어를 액션객체에 같이 담아서 보내줄 때 그것을 같이 담아 주는 것을 payload라고 한다.
payload 사용 방법
사용자가 값을 받을 input 구현 -> action creator 작성 -> reducer 작성 ->
counter.js 파트
action creator: payload가 필요한 action creator에서는 함수를 선언할 때 매개변수자리에 payload를 선언해 주어야 한다. 왜? action creator를 사용하는 컴포넌트에서 reducer로 보내고자 하는 payload를 인자로 넣을 예정이기 때문이다.
우리가 store에 있는 값을 가져오기 위해서 사용한 hook이 뭘까? useSelector이다.
Ducks Pattern
1. reducer 함수를 export default 한다
2. action creator 함수들을 export 한다
3. action의 type은 app reducer action-type의 형태로 작성한다 (module 파일 1개에 action-type, action creator, reducer가 모두 존재하는 작성 방식)
요약
Reducer로 보내는 action 객체에 어떤 정보를 같이 담아 보내고자 한다면, payload를 이용한다. Payload는 action creator를 생성할 때 매개변수 자리에서 받을 준비를 하고, 반환하는 액션객체에 payload란 key와 받은 매개변수를 value로 하여 구현한다. Reducer에서 payload를 사용하고자 할때는 action.payload 이렇게 사용할 수 있다.
그리고 ES6에서 key와 value가 같으면 축약해서 작성할 수 있다.
MINUS_NUMBER 구현 순서
1. counter.js로 넘어가서 action value 추가
2. action creator 추가
3. reducer에 case 추가
4. App.js 로 넘어가서 dispatch 선언 확인
5. 빼기 버튼을 눌렀을 때 실행할 이벤트 핸들러 생성
6. 빼기 버튼에 onClick 이벤트 핸들러 연결
7. action creator import
8. 빼기 핸들러에 dispatch 부분 추가
React-router-dom을 사용함으로써 SPA 기반 리액트 프로젝트 안에서 여러 페이지를 가진 앱을 만들 수 있다.
CLI: yarn create react-router-dom
아래의 순서로 라우터 돔을 사용한다:
1. 페이지 component를 만들어 준다. 이동해야 할 페이지를 여러개 만들어서 Router.js를 만들어 라우터 설정코드를 작성한다.
2. App.js에 import하고 적용시킨다.
이번에는 url 한개당 page component을 한개씩 매칭해 줄것이다. 이 한개의 url을 route라고 한다. 그리고 route를 설정하는 코드는 Router.js라는 파일을 별도로 분리해서 많이 작성한다.
Routes에는 react-router-dom에서 지원하는 props들이 있다.
<Route path="/" element={} />
입력후, App.js에 Router.js를 import한다. Router를 App 컴포넌트에 넣어주는 이유는 우리가 만든 프로젝트에서 가장 최상에 존재하는 컴포넌트가 App.js이기 때문이다. 즉, 우리가 어떤 컴포넌트를 화면에 띄우던 항상 App.js를 거쳐야 한다. 그래서 path별로 분기가 되는 Router.js파일을 App.js에 위치시키고 우리의 서비스를 이용하는 모든 사용자가 항상 App.js에서 Router.js를 거치도록 코드를 구현해주는 것이다.
React에서 useState와 같은 hook을 제공하는 것처럼, react-router-dom에서도 우리가 유용하게 사용할 수 있는 hook을 제공한다.
useNavigate: 다른 페이지로 보내고자할 때 사용
useLocation: react-router-dom을 사용하면 우리가 현재 위치하고 있는 페이지의 여러가지 정보를 추가적으로 얻을 수 있다. 이 정보를 이용해 페이지 안에서 조건부 렌더랑을 사용하는 등 여러가지 용도로 활용할 수 있다.
Link: HTML태그 중에 a태그 (하이퍼링크 기능)의 기능을 대체하는 api이다. jsx에서 링크태그를 사용해야 한다면 반드시 Link를 이용해서 구현해야 한다. 왜냐? a태그를 사용하면 페이지를 이동하면서 브라우저가 새로고침되기 때문인데, 그러면 모든 컴포넌트가 다시 렌더링 되어야 하고 또한 우리가 redux나 useState를 통해서 메모리 상에 구축해놓은 모든 상태값이 초기화되기 때문. 이것은 곧 성능에 악영항을 줄 수 있고, 불필요한 움직임이다.

Children
우리는 layout에 children을 활용할 수 있다. 어떤 컴포넌트들은 어떤 자식 element가 들어올지 미리 예상 할 수 없는 경우가 있다. 범용적인 박스역할을 하는 사이드바 또는 dialog와 같은 컴포넌트에서 특히 자주 볼 수 있다. 여기에서 말하는 범용적인 박스 역할을 하는 컴포넌트란, 크게 봤을 때 layout역할을 하는 컴포넌트라고 할수 있다. Children에 대해서 공부하다보면 composition (합성) 이라는 말을 많이 보게 될것. 이번에는 children props를 가지고 페이지 layout을 만들면서 개별적으로 존재한 header, footer 페이지를 합성해서 개발자가 의도하는 ui를 만들어주는 layout 컴포넌트를 만들것이다.
1. shared 폴더에 Layout.js 파일 생성
2. Router.js에서 Layout으로 감싸줌
3. App.js에서 router import
더 알아보기:
HTTP란? URI란? 둘의 차이점은?
Dynamic route (동적 라우팅): URL안에 유동적인 값을 넣어서 특정 페이지로 이동하게끔 구현하는 방법 (ex. 쿠팡- 같은 페이지, 같은 레이아웃이지만 아이템아이디마다 다름)
useParams: dynamic route에서 path에 입력된 아이디 값을 가져오는 데에 쓰이는 hook. 각각의 고유한 아이디값을 조회 할 수 있다.
Dynamic route 사용시, element에 설정된 값은 같은 컴포넌트를 동일하게 렌더링 한다.
Dynamic route를 성정할 때는 Router.js에서 아이디를 넣고

Works.jsx에서 param에서 useParams을 이용해서 컴포넌트 안에서 조회할 수 있다.
