React(리액트)_Counter_with Redux(리덕스)
* redux 의 기본 원칙
1) redux 의 상태(state)는 store에 보관된다.
2) store는 1개만 만든다.(store는 reducer 함수에 의해 만들어진다. reducer는 복수개 사용 가능)
3) store의 state를 변경할 수 있는 유일한 방법 : action dispatch [ action을 store에 dispatch ]
- store내에 존재하는 reducer가 action을 받아서 각 action type에 따라 해당하는 reducer 함수(순수함수)를 작동시키고, 각각의 reducer 함수의 작동에 의해 state를 변화시킨다.
- 즉, react component 에서 store로 dispatch 하는 action에 따라 store 내의 reducer 함수가 작동하여 store 내의 state 값을 변화시킨다.
* Actions
- action은 state 변화를 정의하기 위한 객체.
- action은 반드시 type(string 형태)을 가져야 함. type 외에도 reducer의 작동에 영향을 미칠 다른 요소(ex: text)가 있다면 추가할 수 있음.
- action creators (액션 객체를 만드는 함수)
* Reducers
- Action은 state 변화를 정의하기 위한 요소들을 가지고 있지만, 그 요소들을 이용해서 어떻게 state를 변화시킬 것인지를 특정하는 함수가 reducer임.
------------------------------------------------------------------------------
*********** 리덕스를 이용한 카운터 만들기 Tutorial: React(리액트)_Counter_with Redux(리덕스) **************
* Counter sample 화면
1. Counter app 의 src 폴더 구조
- src-main.js
- src-actions, reducers, components, containers
- src-actions-ActionType.js, index.js
- src-reducers-counterReducer.js, index.js
- src-components-App.js
- src-containers-AddCounter.js, Counter.js, RemoveCounter.js
2. src-main.js
- main.js는 app.js를 자식 component로 가지는 가장 상위의 파일임.
- 역할 : store를 생성해서 <Provider>로 <App> 을 감싸서 App에 store를 전달.(Provider의 props로 store를 전달
--> App에 store가 전달되면, App 및 App의 모든 하위 component는 store의 모든 data에 접근 가능함.
- store 생성 : const store = createStore(reducer);
3. src-components-App.js
- App.js(Dumb Component, Presentational Component)는 container component 들을 rendering 하여 화면을 구성하는 주요 파일임.
- 렌더링되는 3개의 container component(Smart Component) : Counter, AddCounter, RemoveCounter
- Dumb Component는 container component를 child component로 가지고, 그들을 렌더링하는 역할만을 수행함. Dumb Component는 store와 interaction을 하지 않으며, store의 state를 읽어오지 못함.
- Smart Component는 store와 interaction 하며, store의 current state를 get 하거나, store에 action을 dispatch 하여 store의 state 를 변화시키기도 함.
4. src-containers-AddCounter.js, Counter.js, RemoveCounter.js
- Smart Component 3종
- Smart Component는 store와 interaction 하며, store의 current state를 get 하거나, store에 action을 dispatch 하여 store의 state 를 변화시키기도 함.
src-containers-AddCounter.js
- AddCounter component : Add 버튼 클릭시 Counter 숫자가 1씩 증가하도록.
- Add 버튼 클릭시 +1 기능을 하는 액션을 dispatch의 parameter로 전달하면 됨.( ADD_COUNTER actionType을 dispatch)
- addCounter 액션 생성함수를 실행하면 ADD_COUNTER action이 생성됨.(즉, addCounter() = ADD_COUNTER action)
- 버튼의 onClick 속성에 (e) => {this.props.dispatch(addCounter())} 를 정의함.
- mapDispatchToProps(dispatch)를 이용해서 dispatch(addCounter())를 addCounter component의 Props로 받아옴.
- mapDispatchToProps(dispatch)의 return 내용으로는 { actions: bindActionCreators(addCounter, dispatch) } 를 사용.
- bindActionCreators의 parameter로는 액션 생성함수와 dispatch 함수를 전달.
- connect 함수에 mapDispatchToProps 를 인자로 전달하면 새로운 함수가 리턴되며, 그 함수는 인자로 Props를 받을 대상 component가 들어간다. (즉, 자기 자신 component에게 Props를 전달하려면 AddCounter를 넣고, 다른 파일의 component(Dumb Component 등)를 넣을 수도 있음.)
src-containers-Counter.js
- mapStateToProps(state) 를 이용해서 count 값을 store로부터 this.props.count 로 전달받아서 사용.
- connect(mapStateToProps)(Counter) : state 값을 Props로 Counter component(자기 자신)에 전달.
// src-containers-Counter.js
src-containers-RemoveCounter.js
- store에 connect하여 this.props.dispatch(removeCounter()) 를 props로 전달받아 사용.
5. src-actions-ActionType.js, index.js
src-actions-ActionType.js
- 액션 타입 정의
src-actions-index.js
- 액션 생성함수 정의
- type 외의 요소로 증가/감소 숫자인 1을 payload 값으로 정의.
6. src-reducers-counterReducer.js, index.js
src-reducers-counterReducer.js
- counterReducer 정의 : innitialstate(state=0)와 action 을 parameter로 전달.
- action.type에 따라 switch-case 문으로 분기
src-reducers-index.js
- 리듀서가 복수인 경우를 대비해 combineReducers 함수를 이용해 최종 리듀서인 counterApp을 생성.
- main.js 에서 import reducer from './reducers'; 로 사용하게 됨.
'프로그래밍(Programming) > 리액트(React)' 카테고리의 다른 글
[리액트(React) Study Log] [Person App-002] Understanding the Folder Structure (0) | 2019.01.11 |
---|---|
[리액트(React) Study Log] [Person App-001] Using Create Reate App (0) | 2019.01.11 |
React(리액트) : 상태관리 라이브러리 MobX 개념 (0) | 2018.10.13 |
React(리액트) ; Lifecycle API (0) | 2018.08.28 |
React(리액트) ; props & state (0) | 2018.08.28 |