redux
리덕스의 큰 그림을 살펴보면 위와 같다.
우리가 해야할 것들
- 액션 타입 생성
- 액션 생성 함수
- 리듀서 생성
- 리듀서 합치기 (combine)
- react와 연결 - 스토어 생성(가장 최상위의 index.js) + Provider로 감싸기 + 크롬 개발자 연결
- react와 연결 - container component(redux와 연결된 component) 에서 연결
- react와 연결 – connect함수 ,dispatch하기
리덕스를 사용할 때 필수 설치
npm install --save react-redux
: react에서 redux를 사용할 때 필요.npm install --save redux
: redux 자체 함수를 사용하기 위해 필요.- ex)createStore, bindActionCreators 함수 사용시
npm install --save redux-devtools-extension
: 크롬에서 현재 스토어를 눈으로 보기 위해 설정해줘야한다.
UI준비하기
- Container Component : 리덕스와 연동되어 있는 컴포넌트, 리덕스로부터 상태를 받아오기도 하고 스토어에 액션을 dispatch 한다.
- Presentational Component : 상태관리 이뤄지지 않고, 그냥 보여주기만 하는 컴포넌트
폴더 구조
- src/container 에는 리덕스와 연동된 컴포넌트를 저장한다.
- src/components 에는 Presentational component 들이 들어간다.
- src/module 에는 아래에서 설명되는 리덕스 관련 코드들이 들어가는 폴더가 된다.
리덕스 관련 코드들
리덕스 관련 코드들은 크게 3가지 역할로 나눌 수 있다.
- 액션 타입
- 액션 생성 함수
- 초기state값 + 리듀서
이 3가지 묶음을 하나의 js파일에 기능별로 정리 하는 것이 Ducks Pattern 이라고 한다.
이렇게 3가지 리덕스의 코드들을 src/module 폴더 안에 각자 이름으로 저장한다. (ex: module/counter.js)
아래 내용들은 모두 src/module/counter.js 내부에 들어간다.
1. 제일먼저 액션 타입을 정의해준다.
const INCREASE = "counter/INCREASE";
const DECREASE = "counter/DECREASE";
이렇게 정의를 해주는데, 이때 타입 앞에 폴더을 앞에 붙여주게 되면(counter
/INCREASE) 다른 곳에 사용시 겹치지 않는다.
2. 두번째로 액션 생성 함수를 만들어 준다.
export const increase = () => ({ type: INCREASE });
export const decrease = () => ({ type: DECREASE });
액션 타입이 들어간 액션 생성을 하는 함수를 만든다. 추가적인 인자가 들어가는 것이 없어 간단하게 보여진다.
주의할 것은 export가 붙는데 이 함수를 다른 파일에서 불러와 사용해야 한다는 것.
ex) dispatch에 액션 생성 함수를 넣어줘야 하기 때문에 !! (dispatch는 다른파일에서 사용된다.)
3. 초기 state 값 설정 + 리듀서 생성
리듀서에는 인자 2개가 들어간다.
- state값
- action
인자 2개가 들어가는 이유(reducer의 역할) : action 값에 변화가 있으면, 기존에 있는 state 값을 참고해서 다시 새로운 state를 내보낸다
state값 설정
const initialState = {
number: 0
};
이렇게 해서 입력값이 없어도 state값이 0 이라고 지정해야한다. 설정 안할시 undefined로 되어있기 때문에!
reducer 함수 작성
function counter(state = initialState, action) {
switch (action.type) {
case INCREASE:
return {
number: state.number + 1
};
case DECREASE:
return {
number: state.number - 1
};
default:
return state;
}
}
export default counter;
이 부분에 대해서 설명이 좀 길다. 내가 이해하는데 오래 걸렸기 때문.
function counter(state=initialState, action)
이 부분에 대한 해석: 리듀서 함수를 만드는데, 이름을 counter라는 이름으로 reducer의 역할을 하는 함수를 만든다. 인자로 state와 action이 들어간다.
state는 위에서 선언한 initialState가 들어간다.그렇다면 state는
state : {
number:0
}
위 상태이다. 그리고 action은 이 dispatch에 의해서 들어오게 될 것이다.(아직 dispatch를 사용하지 않아서 이 부분은 빠져있을뿐.)
이제 뒷부분을 살펴보자.
{
switch (action.type) {
case INCREASE:
return {
number: state.number + 1
};
case DECREASE:
return {
number: state.number - 1
};
default:
return state;
}
}
export default counter;
인자 2개가 들어왔으면 실행되는 함수내용 인데 switch(action.type)은 정확한 해석은 모르겠다.
action객체의 type을 보겠다는 것으로 해석된다. case INCREASE: action의 type이 위에서 선언한 INCREASE 이면 return 하는 내용을 담고 있다.
여기서 중요한 개념이 스프레드 연산자 인데, state의 여러 값 중에서 하나만 바꿀 때는
...state
라고 입력하여 나머지 state는 건들지 않고 바꿀 state 값만 입력해주면 된다.
그리고 default: return state는 바뀌는 값이 없으면 현재 state를 내보내겠다고 선언한 것이다.
맨 마지막 export default counter; 선언을 하여 내보낼 수 있게 해준다.
export default 와 export 차이점 ?
export default counter;
VS export const INCREASE = () =>({type:INCREASE})
export default 는 단 한개만 내보낼 수 있다.
하지만
export 는 여러개를 내보낼 수 있다.
??????????????????? 이게 무슨말이냐 하면
다른 파일에서 export 와 export default 를 사용할 때 방식이 다르다.
import counter from './counter;
import {INCREASE, DECREASE} from './counter;
이렇게 다르다. 사실 위 작성법은 import counter , {INCREASE, DECREASE} from './counter;
라고 쓸 수 있다.
이렇게 리.덕.스 관련 함수들을 만들었다.
우리는 이제 action과 reducer를 만들었다.
만들기만 했을 뿐 연결이 되지 않아 덩그러니 혼자 있는 상태이다.
우리가 해야할 것들
1. 액션 타입 생성
2. 액션 생성 함수
3. 리듀서 생성
- 리듀서 합치기 (combine)
- react와 연결 - 스토어 생성(가장 최상위의 index.js) + Provider로 감싸기 + 크롬 개발자 연결
- react와 연결 - container component(redux와 연결된 component) 에서 연결
- react와 연결 – connect함수 ,dispatch하기