React
[리액트] Redux
드비디
2024. 10. 22. 14:39
Redux란 무엇인가?
Redux(리덕스)란 JavaScript(자바스트립트) 상태관리 라이브러리이다.
Redux(리덕스)의 본질은 Node.js 모듈이다.
Redux를 사용하는 이유
먼저 상태란?
- React에서 State는 component 안에서 관리되는 것이다.
- 자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능 하다.
- 자식 컴포넌트들 간의 데이터를 주고 받을 때는 상태를 관리하는 부모 컴포넌트를 통해서 주고 받는다.
- 그런데 자식이 많아진다면 상태 관리가 매우 복잡해진다.
- 상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야한다. => Props drilling 이슈
Redux의 사용의 좋은 예는 props즉 상태를 전이 할 때 한 단계식 내리는것이 아닌 store를 통해 밖에서 상태를 전달해줄 수가 있다.
Store (스토어)
Store(스토어)는 상태가 관리되는 오직 하나의 공간이다.
- 컴포넌트와는 별개로 스토어라는 공간이 있어서 그 스토어 안에 앱에서 필요한 상태를 담는다.
- 컴포넌트에서 상태 정보가 필요할 때 스토어에 접근한다.
Action (액션)
- Action(액션)은 앱에서 스토어에 운반할 데이터를 말한다. (주문서)
- Action(액션)은 자바스크립트 객체 형식으로 되어있다.
Reducer (리듀서)
- Action(액션)을 Store(스토어)에 바로 전달하는 것이 아니다.
- Action(액션)을 Reducer(리듀서)에 전달해야한다.
- Reducer(리듀서)가 주문을 보고 Store(스토어)의 상태를 업데이트하는 것이다.
- Action(액션)을 Reducer(리듀서)에 전달하기 위해서는 dispatch() 메소드를 사용해야한다..
Redux 간단하게 시작해보기
# NPM
npm install redux
npm install react-redux
# Yarn
yarn add redux react-redux
먼저 리덕스를 설치한다.
1. RootReducer 정의
- 여러 reducer을 사용하는 경우 reducer을 하나로 묶어주는 메소드
// reducers/index.js
import { combineReducers } from "redux";
import counter from "./counter";
const rootReducer = combineReducers({
counter
});
export default rootReducer;
2. 세부 reducer 정의
// reducers/counter.js
export const INCRESE = "COUNT/INCRESE";
export const increseCount = count => ({ type: INCRESE, count });
const initalState = {
count: 0
};
const counter = (state = initalState, action) => {
switch (action.type) {
case INCRESE:
return {
...state,
count: action.count
};
default:
return state;
}
};
3. store 만들기
import { compose, createStore, applyMiddleware } from "redux";
import rootReducer from '../reducers/index';
import thunk from "redux-thunk";
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
: compose;
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));
export default store;
4. app에 store 넣고, 만든 reducer 반영
<Provider> 안써서 엄청나게 눈물을 흘리면서 왜 안될까 찾았던…
// index.js
import React from "react";
import ReactDOM from "react-dom";
import { createStore, applyMiddleware, compose } from "redux";
import { Provider } from "react-redux";
import logger from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";
import App from "./App";
import rootReducer from "./reducers";
// 배포 레벨에서는 리덕스 발동시 찍히는 logger를 사용하지 않습니다.
const enhancer =
process.env.NODE_ENV === "production"
? compose(applyMiddleware())
: composeWithDevTools(applyMiddleware(logger));
// 위에서 만든 reducer를 스토어 만들때 넣어줍니다
const store = createStore(rootReducer, enhancer);
ReactDOM.render(
// 만든 store를 앱 상위에 넣어줍니다.
<Provider store={store}>
<App />
</Provider>
document.getElementById('root'),
);
5. 컴포넌트에서 redux 사용하기
import { useSelector, useDispatch } from "react-redux";
import { increseCount } from "reducers/count";
// dispatch를 사용하기 위한 준비
const dispatch = useDispatch();
// store에 접근하여 state 가져오기
const { count } = useSelector(state => state.counter);
const increse = () => {
// store에 있는 state 바꾸는 함수 실행
dispatch(increseCount());
};
const Counter = () => {
return (
<div>
{count}
<button onClick={increse}>증가</button>
</div>
);
};
export default Counter;
Reference