반응형
리덕스
리액트 상태 관리 라이브러리
어플리케이션의 상태를 저장,관리
React-redux를 통해 리액트에서 사용 가능
리덕스를 사용하는 이유?
리액트는 컴포넌트를 쪼개서 하위, 하위, 하위, 컴포넌트를 구성하고 있다(프로젝트 규모가 클수록 컴포넌트 구조가 복잡하다)
리액트의 컴포넌트는 각각의 state를 쓰고 있는데 보통 같은 state를 쓰는 같은 계층의 컴포넌트가 있다면 상위 컴포넌트에서 props로 넘겨줘야 한다
-> 규모가 클수록 복잡해진다(같은 state를 많은 컴포넌트에서 쓴다면 복잡해진다)
-> 그래서 리덕스를 통해 필요한 컴포넌트에서만 state를 쓸 수 있게 할 수 있다.
개념
component- 화면을 보여주는 뷰
store - 프로젝트 상태에 관한 데이터들이 담겨있다.(단 하나의 공간)
subscribe - 저장되어 있는 공간을 컴포넌트가 저장되어 있는 데이터를 구독을 통해 가져옴(action과 reducer를 통해)
action - 프로젝트의 store, 저장소로 data를 보내는 방법
reducer - action을 통해 어떠한 행동을 정의했다면, 그 결과 상태가 어떻게 바뀌는지 정의하는 함수
store.js 예제를 통해 맛보기
npm install redux
npm install redux-logger
// redux 라이브러리를 불러온다
const redux = require('redux');
// 상수에 리덕스 안의 createStore 함수를 담았다
const createStore = redux.createStore;
// actions
// action-types
// 액션 타입을 정의했고
const ADD_SUBSCRIBER = 'ADD_SUBSCRIBER';
// 액션 코드를 작성
const addSubscriber = () => {
return {
type: ADD_SUBSCRIBER, // 타입이 ADD_SUBSCRIBER를 가진 오브젝트를 반환해주는 액션이 된다
};
};
//reducers
const initialState = {
subscribers: 365,
};
const reducer = (state = initialState /* 초기값 설정 */, action) => {
// action.type을 통해 핸들링
switch (action.type) {
case ADD_SUBSCRIBER:
return {
...state, // 기존 state 카피를 한다
subscribers: state.subscribers + 1,
};
// 아무 액션이 없을 경우 state 리턴
default:
return state;
}
};
// store
// 첫번째 인자에는 리듀서를, 두번째 인자에는 미들에어를 넘길 수 있다.
const store = createStore(reducer);
// subscribe를 통해 state 값이 바뀌면 알 수 있다.
store.subscribe(() => {
console.log('subscribe==>>', store.getState());
});
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
- 터미널에서 node store.js 실행 시
subscribe==>> { subscribers: 366 }
subscribe==>> { subscribers: 367 }
subscribe==>> { subscribers: 368 }
subscribe==>> { subscribers: 369 }
logger 적용
const redux = require('redux');
// redux-logger 불러온다
const reduxLogger = require('redux-logger');
const createStore = redux.createStore;
const applyMiddleware = redux.applyMiddleware;
const logger = reduxLogger.createLogger();
const ADD_SUBSCRIBER = 'ADD_SUBSCRIBER';
const addSubscriber = () => {
return {
type: ADD_SUBSCRIBER,
};
};
const initialState = {
subscribers: 365,
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_SUBSCRIBER:
return {
...state,
subscribers: state.subscribers + 1,
};
default:
return state;
}
};
// store
// 첫번째 인자에는 리듀서를, 두번째 인자에는 미들웨어를 넘길 수 있다.
const store = createStore(reducer, applyMiddleware(logger));
// subscribe를 통해 state 값이 바뀌면 알 수 있다.
// store.subscribe(()=>{
// console.log('subscribe==>>', store.getState())
// });
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
- 터미널에서 node store.js 실행시
- 시간과, 이전 값, 어떻게 변했는지 알 수 있음
action ADD_SUBSCRIBER @ 17:34:49.834
prev state { subscribers: 365 }
action { type: 'ADD_SUBSCRIBER' }
next state { subscribers: 366 }
action ADD_SUBSCRIBER @ 17:34:49.846
prev state { subscribers: 366 }
action { type: 'ADD_SUBSCRIBER' }
next state { subscribers: 367 }
action ADD_SUBSCRIBER @ 17:34:49.847
prev state { subscribers: 367 }
action { type: 'ADD_SUBSCRIBER' }
next state { subscribers: 368 }
action ADD_SUBSCRIBER @ 17:34:49.847
prev state { subscribers: 368 }
action { type: 'ADD_SUBSCRIBER' }
next state { subscribers: 369 }
reducer가 여러개일 때
const redux = require('redux');
const reduxLogger = require('redux-logger');
const createStore = redux.createStore;
const applyMiddleware = redux.applyMiddleware;
const logger = reduxLogger.createLogger();
// 두개의 리듀서를 쓰기 위해
const combineReducers = redux.combineReducers;
// actions
// action-types
// 액션 타입을 정의했고
const ADD_SUBSCRIBER = 'ADD_SUBSCRIBER';
const ADD_VIEWCOUNT = 'ADD_VIEWCOUNT';
// 액션 코드를 작성
const addSubscriber = () => {
return {
type: ADD_SUBSCRIBER,
};
};
const addViewCount = () => {
return {
type: ADD_VIEWCOUNT,
};
};
//reducers
const initialState = {
subscribers: 365,
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_SUBSCRIBER:
return {
...state,
subscribers: state.subscribers + 1,
};
default:
return state;
}
};
const viewState = {
viewCount: 100,
};
const viewReducer = (state = viewState, action) => {
switch (action.type) {
case ADD_VIEWCOUNT:
return {
...state,
viewCount: state.viewCount + 1,
};
default:
return state;
}
};
// 스토어에 새로운 리듀서인 viewReducer를 추가해야 하는데 두개의 리듀서를 함께 넘기기 위해 필요한게
// combine-reducer이다 -> 리덕스 라이브러리에 포함되어 있음
// object를 인자로 넘겨 컴바인된 리듀서가 생성되도록
const rootReducer = combineReducers({
view: viewReducer,
reducer: reducer,
});
// store에 컴바인된 리듀서를 넘긴다
const store = createStore(rootReducer, applyMiddleware(logger));
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addSubscriber());
store.dispatch(addViewCount());
store.dispatch(addViewCount());
- 터미널에서 node store.js 실행 시
action ADD_SUBSCRIBER @ 17:46:30.434
prev state { view: { viewCount: 100 }, reducer: { subscribers: 365 } }
action { type: 'ADD_SUBSCRIBER' }
next state { view: { viewCount: 100 }, reducer: { subscribers: 366 } }
action ADD_SUBSCRIBER @ 17:46:30.448
prev state { view: { viewCount: 100 }, reducer: { subscribers: 366 } }
action { type: 'ADD_SUBSCRIBER' }
next state { view: { viewCount: 100 }, reducer: { subscribers: 367 } }
action ADD_SUBSCRIBER @ 17:46:30.448
prev state { view: { viewCount: 100 }, reducer: { subscribers: 367 } }
action { type: 'ADD_SUBSCRIBER' }
next state { view: { viewCount: 100 }, reducer: { subscribers: 368 } }
action ADD_SUBSCRIBER @ 17:46:30.449
prev state { view: { viewCount: 100 }, reducer: { subscribers: 368 } }
action { type: 'ADD_SUBSCRIBER' }
next state { view: { viewCount: 100 }, reducer: { subscribers: 369 } }
action ADD_VIEWCOUNT @ 17:46:30.449
prev state { view: { viewCount: 100 }, reducer: { subscribers: 369 } }
action { type: 'ADD_VIEWCOUNT' }
next state { view: { viewCount: 101 }, reducer: { subscribers: 369 } }
간단 요약
1. 라이브러리를 불러오고
2. 액션을 통해서 액션 타입을 정의
3. 액션을 핸들링 해주는 리듀서 작성(리듀서는 state, action을 넘겨 받는다)
4. combineReducers를 통해 여러가지 리듀서를 컴바인 할 수 있다.
반응형
'리액트' 카테고리의 다른 글
커스텀 훅 (0) | 2022.02.19 |
---|---|
간단하게 이미지 슬라이드 구현하기 (0) | 2022.02.04 |
리액트 리코일 (0) | 2022.01.23 |
(리액트를 다루는 기술) 8장 Hooks (0) | 2021.04.08 |
(리액트를 다루는 기술) 6장 컴포넌트 반복 (0) | 2021.04.01 |