Redux란?
Redux는 JavaScript 상태 관리 라이브러리라 JavaScript든 React든 잘 어울린다.
- 초기 설정
- JavaScript에서 Redux를 사용하려면 따로 설정할 게 없다.
- React에서 Redux를 사용하려면 index.js에 App.js를 Provider 컴포넌트로 감싸 앱의 다른 컴포넌트에서 store를 사용할 수 있도록 해야한다.
import { Provider } from "react-redux"; import store from "./store"; // state가 저장되어 있는 store 파일 위치 ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById("root") );
- 메소드
- useSelector() : state 데이터 읽기
useSelector(selector: Function, equalityFn?: Function) const todo = useSelector((state) => state); // useSelector를 통해 store의 state를 바로 가져옴
- dispatch : reducer에게 어떻게 수정할 것인 지 action을 보내는 방법
- useSelector() : state 데이터 읽기
import { useDispatch } from 'react-redux';
cosnt dispatch = useDispatch(); // dispatch로 재선언하여 사용한다.
store.dispatch({key: value});
const countModifier = (count = 0, action) => {
// const countModifier = (countStore = 0, { type: "ADD" })와 같은 의미
if (action.type === "ADD") return count + 1;
return count;
};
const countStore = createStore(countModifier);
countStore.dispatch({ type: "ADD" });
왜 Redux가 필요한가?
컴포넌트 간의 상태 관리는 props를 활용할 수 있지만 컴포넌트가 복잡하고 많아지면 props를 통한 상태 관리가 어려워진다.
특히 여러 컴포넌트를 거쳐 상태 값을 전달해야 하는 경우, 이로 인해 코드의 가독성이 떨어지고 유지보수가 어려워진다.
이러한 상황에서 Redux를 도입하면 상태 관리를 효과적으로 할 수 있다. Redux는 전역 상태 관리 라이브러리로 앱의 상태를 하나의 저장소에서 효율적으로 관리하여 여러 컴포넌트 간에 손쉽게 상태를 공유하고 업데이트할 수 있다.
store
data(state)를 저장하는 저장소이다.
- 특징
- store를 수정하기 위해선 action을 보내야만 수정이 가능하다.
- 메소드
- createStore(reducer) : store 생성
- reducer이 필요하다.
- subscribe(listener) : store 안에 있는 변화 감지하면 인자값으로 준 리스너를 실행
- 변경사항에 대한 리스너를 추가한다.
- 리스너는 액션이 보내져서 상태 트리의 일부가 변경될 수 있을 때마다 호출된다.
- getState() : 현재 store의 data 값 읽기
- createStore(reducer) : store 생성
import { createStore } from "redux";
const countModifier = (count = 0) => {
// const countModifier = (countStore = 0)와 같은 의미
// countModifier는 reducer이며 state의 기본값을 0으로 설정
return count;
};
const countStore = createStore(countModifier); // createStore의 인자로 reducer가 필요
countStore.dispatch({ type: "ADD" });
const onChange = () => {
console.log(countStore.getState());
};
countStore.subscribe(onChange); // store안의 변화를 감지하면 onChange 실행
state
변경이 필요한 data를 말하며 이 application에서 바뀌는 data이다.
- 특징
- single source of truth
- read-only
- mutate 불가능 ⇒ mutating state 대신 new state objects를 리턴
const reducer = (state = [], action) => { switch (action.type) { case ADD: // reducer 내에서 return 된 값은 store의 state가 되는데 이때 state는 직접적으로 mutate를 하면 안되므로 // 직접적으로 mutate하는 방법인 state.push(~)가 아닌 다음과 같은 방법으로 추가된 새로운 배열을 return return [...state, {text: action.text, id: action.id}]; case DELETE: // filter 함수를 통해 filter 처리된 새로운 배열을 return return state.filter(toDo => toDo !== action.id); } };
- connect() [React-Redux 8.x에서 지원되지만 기본적으로 hooks API를 사용하는 것이 좋다.]
- connect는 argument로 state와 dispatch를 가진다.
- mapStateToProps는 두 종류의 argument와 함께 호출되는 function이다.
- 첫번째 argument는 Redux store에서 온 state이다.
- 두번째 argument는 component의 props이다.
- connect()는 return한 것을 component의 prop에 추가해준다.
reducer
data를 바꾸고 수정하는 함수를 말하며 reducer가 return하는 것은 application에 있는 data가 된다.
현재 상태의 application과 함께 불려지는 function (+ with action)이다.
reducer로 인자로 들어오는 action의 타입으로 switch가 자주 쓰인다.
const reducer = (state = [], action) => {
switch (action.type) {
case ADD:
...
case DELETE:
...
}
};
action
redux에서 function을 부를 때 쓰는 두 번째 parameter 혹은 argument으로 reducer와 소통하기 위한 방법
- 특징
- 무조건 object여야 한다.
- property(key)는 항상 type이어야 한다.
redux의 흐름
- data의 store를 create하고, store에게 data의 reducer를 알려준다.
- dispatch로 message(action)을 store에 전송한다.
- 이렇게 store, dispatch, action을 말해주면 redux가 reducer를 호출해서 매개변수에 current state와 my action을 넣어줘서 실행한다.
- reducer가 실행되면 data를 바꿔주고 return으로 반환되는 값은 다시 application의 data가 된다.
'프론트엔드 > JavaScript' 카테고리의 다른 글
[프론트엔드] 호이스팅(Hoisting) 이란? (0) | 2023.12.11 |
---|