store -> 스토어는 리듀서의 집합체이다
스토어 안에 리듀서가 포함되어 있다.
그래서 스토어는 상태값도 가지고있고, 리듀서도 가지고있다.
스토어의 내장 함수 중 dispatch가 있다.
모듈은 state의 그룹이다.
스토어와 모듈은 자동으로 연결 되지 않으므로 따로 연결시켜 주어야 한다
// 원래 있던 코드
import { createStore } from "redux";
import { combineReducers } from "redux";
// 새롭게 추가한 부분
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter: counter, // <-- 새롭게 추가한 부분
});
const store = createStore(rootReducer);
export default store;
스토어와 모듈 연결 확인하는 법 : useSelector (react-redux hook)
컴포넌트에서 스토어를 조회한다.
하면 이렇게 카운터 안에 내가 넣은 값이 잘 있음. 스토어 확인 완료
이제 컴포넌트에서 number, name 값이 필요하다면
const number = useSelector(state => state.counter.number);
이렇게 꺼내쓰면 됨
정리!
initialState
, Reducer
가 있다.configStore.js
에서 한다.useSelector
를 사용해야 한다.useSelector((state)⇒state)
에서 state
는 모든 모듈의 state 를 조회할 수 있는 값이다.
상태관리 흐름을 살펴보기 전에 기본으로 알고 갈 것
전역 상태 관리
1. 전역으로 볼 수 있는 데이터가 있다.
2. 그 데이터를 참조하는 component가 있다. 개중에 어떤 것들은 원본값을 수정하고 싶어 함
3. 바뀐 값을 모두가 볼 수 있게 해야 함
데이터를 받아 가는것을 subscribe 라고 함
이 데이터를 가져가서 수정할 때 원본값에 바로 접근 X
데이터를 바꿀 수 있는 함수를 호출해서 데이터를 수정하고 어떤 데이터를 바꿨는지 모두에게 알려준다.
데이터들이 있는 곳 store
실제로 데이터를 수정할 수 있는 곳 reducer
데이터 수정할 때 1. 수정 예고 2. 수정 3. 수정 알림 이런 과정을 거쳐야 한다
A component와 B component가 스토어에서 데이터를 subscribe 하고 있다
A가 데이터를 1에서 2로 바꾸고자 할 때 액션을 디스패치 한다고 말한다.
1에서 2로 바꾸는 과정이 리듀서에서 일어나고, 스토어에서 값이 변경됐다고 알림
새로운 값을 받아와서 컴포넌트에서 리렌더링이 일어남
리덕스 흐름 이해하기
action : 무엇을 하라고 보내는 명령 (내가 이 값을 수정하겠다 - 액션을 일으킨다)
액션 객체 : 행동을 코드로 나타냈을 때 객체로 만든다. 그래서 결론 액션 객체는 명령모음집 ~
액션 객체는 반드시 type이라는 key를 가져야 함 (type은 행동의 이름)
액션 객체를 리듀서에 보내는 법 : useDispatch
dispatch라는 변수 먼저 생성해줘여 함
이 때 액션 객체에 타입 지정을 하지 않으면 이런 오류가 뜬다.
액션객체에서 로직 코드는 스위치문으로 작성한다.
리듀서에서 상태를 바꾸는 방법
1. dispatch로 액션객체를 전달받음
2. action의 type을 하나씩 검사해서 일치하는 케이스를 찾는다. 스위치 사용
3. 타입과 케이스가 일치할 때 해당 코드를 실행해서 새 state를 리턴한다.
4. 리듀서가 새로운 state 를 반환하면 그것이 새 모듈의 state가 된다
여기서 케이스란 ? 액션 타입입니다.
정리!
액션 객체의 밸류를 바꿔야 할 때, 액션객체의 개수가 너무 많아서 일일히 수정이 불가능하다면?
하드코딩을 하면 이러한 번거로움이 있다.
관리의 편의성을 위해 액션 객체를 한 곳에서 관리할 수 있도록 하는 것이 action creator 이다.
const PLUS_ONE = "PLUS_ONE" // value값을 상수로 생성
// 액션 객체를 반환하는 함수 생성 - plusOne 은 외부에서도 써줘야 하니까 export 해주기
export const plusOne = () => {
return {
type: PLUS_ONE,
};
};
자세한 것은.. 나의 vscode 참고
action creator를 컴포넌트에서 사용하는 법
1. export 된 것 import 하기
2. dispatch() 부분 지우고 action creator 넣기
dispatch() 안에 객체만 들어가야 하는데 어떻게 함수가?
-> {type: “PLUS_ONE”} === plusOne() 이라서 그렇다네요
함수를 실행한다 = 함수의 return 값과 같다
const one = () => {return 1; } 로 함수를 만들었을 때 one() === 1 입니다.
그렇다면 왜 action creator 를 사용해야 하는지?
1. 휴먼에러 방지 2. 유지보수 효율성 증가 3. 코드 가독성
state를 변경하면서 리듀서에 어떤 값을 같이 보내줘야 할 때 payload 사용
구현 순서
1. 사용자가 입력한 값을 받을 input 구현하기
2. action creator 작성하기
3. reducer 작성하기
4. 기능 테스트하기
여러개의 페이지를 이동할 수 있게 해줌
이때 route를 설정하는 코드는 router.js로 따로 빼서 사용하기 -> app.js에 import해주기
react-router-dom hook
useNavigate : 버튼 클릭했을 때 우리가 원하는 path로 페이지 이동
navigate('보내고 싶은 경로 url')
useLocation
Link : html a 태그의 기능을 대체하는 api
동적 라우팅
path에 :id 붙여서 동적으로 작동할 수 있게 한다 -> useParams 에서 조회할 수 있음