[ 07.09 ] Redux 상태관리(1)
Achievement Goals
🍔 상태 관리 라이브러리가 왜 필요한지 이해할 수 있다.
🍔 Redux의 3가지 원칙이 무엇이며, 주요 개념과 어떻게 연결되는지 이해할 수 있다.
🍔 Redux (혹은 Flux Pattern)에서 사용하는 Action, Reducer 그리고 Store의 의미와 특징을 이해할 수 있다.
🍔 Redux hooks(useSelector, useDispatch)를 사용해 store 를 업데이트할 수 있다.
🍔 상태 관리 라이브러리는 왜필요할까?
기존에 리액트에서의 상태관리는 자식컴포넌트가 부모컴포넌트에게 props를 전달해주고 다른 자식컴포넌트들이 부모 컴포넌트에서 데이터를 가져오는 형식이었다. 이 react 의 고질적인 문제를 props drilling 이라고도 한다.
즉, 자식컴포넌트와 자식컴포넌트 사이의 다이렉트한 상태관리는 공유가 힘들었다.
현실을 반영하여 말하자면
사장 -> 부장 -> 차장 -> 과장 -> 대리 -> 사원
사장이 사원에게 바로 지시하는것이 아니라 몇다리 거쳐서 업무지시를 받아야하는 아주 비효율적인 체계인것이나 다름없다.
예시) 최상단에 있는 App.js 에서 useState 를 통한 상태관리.
사진처럼 관리할 상태들이 몇개 없을경우에는 상관없지만
상태 양이 더 많아지거나 더 큰 프로젝트를 할 경우 복잡하게 느껴질 것이다.
이러한 복잡성을 줄이기 위해 리덕스 라이브러리가 필요한 것이다.
리덕스 사용시 꼽을 수 있는 장점으로,
1. 상태 예측이 가능하다.
2. 유지보수가 용이하다.
3. action 과 state 로그 기록시에는 디버깅에 유리하다.
4. 테스팅이 쉽다.
🍔 Redux의 3가지 원칙
1. single source of truth
동일한 데이터는 항상 같은곳(store)에서 가져온다
2. state is read-only
state 는 항상 읽기전용이지만 action 이라는 객체를 통해 state 가 변경가능하다.
3. changes are made with pure functions
reducer 변경은 순수 함수로만 가능하다.
🍟 store
store 라는 공간은 전역에서 상태관리를 하는 개념으로,
상태관리 정보들을 가져올 수 있는 공간이다.
각 자식컴포넌트들은 더이상 부모가 아닌 store 를 통해 정보를 가져올 수 있다.
*dispatch 는 store에 속한 프로토타입 메소드이다.
const store = createStore(rootReducer);
미들웨어와 redux dev 툴을 위한 소스코드때문에 저렇게 보이지만
자세히 뜯어보면 const store = createStrore(rootRdeucer) 가 보인다.
🍟 Action
store에게 application data 를 운반해주는 역할로,
어떤 행동을 취할지 정의해놓은 것들을 모아둔 객체이다.
액션을 사용할땐 반드시 type 을 명시해야 하며 그 외의 부수적으로 필요한것들은 payload 라는 객체형태에 담기게 된다.
이렇게 모든 변화를 action을 통해 취하는 것은 우리가 만드는 앱에서 무슨 일이 일어나고 있는지 직관적으로 알기 쉽게 하는 역할을 한다.
🍟 Reducer
기존에 있는 상태와 action에서 받은 데이터를 토대로 주소값이 아예 다른 새로운 state를 만들어주는 순수형태 함수이다.
그렇다면 순수함수의 조건은 뭘까?
1. 동일한 인자값을 받으면 항상 동일한 값을 리턴한다.
2. 어디서 호출되든 동일한 결과를 보여준다.
3. 외부에 영향을 주지도, 받지도 말아야 한다.
ex)
function add(a,b){
return a + b
}
// 순수함수
let c = 1;
function add2(a,b){
c = b;
return a + b + c
}
// 외부영향을 받고있으므로 순수함수가 아니다.
앞서 리덕스의 장점으로 말한 state log 기록 시 디버깅이 쉬운것으로 꼽았는데, 이 변경된 state를 로그로 남기기위한 작업을 해야하기 때문에 원본은 변하지 않는 Immutable 한 성질을 가지고 있어야 한다.
이때 Object.assign(target, ...sources) 메소드를 사용하는 것이다. (스프레드도 복사의 개념이기때문에 가능한것으로 알고있음.)
리액트와 연결시키는 dispatch, selector
🍟 useSelector()
컴포넌트와 state 를 연결하는 역할을 한다.
콜백함수를 인자로 받으며 이 콜백함수는 state 값이 들어간다.
🍟 useDispatch()
action 객체를 reducer 로 전달해주는 메소드이다.
액션은 보통 어떠한 이벤트가 일어날때 발생하므로 그 이벤트가 해당하는 컴포넌트에 작성하는것이 좋다.
전체적인 procedure
UI -> Dispatch -> Action(이벤트) -> Store > Reducer > NewStates
디스패치를 통해 이벤트가전달
리듀서에게 전달
리듀서는 타입을 바탕으로 새로운 상태를 만들어낸다.
그 상태가 유아이에 반여이됨.
또 그 반영된게 디스패치 이벤트에의해 일어나고
액션객체에 전달.
전달된 타입이 리듀서에게 가고 또 새로운상태 그게 스토어임.
게속 반복
스토어를 변경하게 할수있는 함수가 리듀서임.
스토어라는 거대한 객체안에 저 메소드들이들어있는거임.
리액트 없이도 사용이 가능하긴함.
redux 설치코드
npm install --save redux
//react로 리덕스 사용하기 기초
1. const {createStore} = require('redux') (노드에서 사용시)
2. 초기상태함수
const initState = (name) =>{
name ='sook'
post = []
}
3. 액션 : 유저네임변경하기 post 추가하기
const changeUsername = (name)=>{
return {
type : 'CHANGE_NAME',
name
}
}
const addPost = (post) =>{
return {
type : 'ADD_POST',
post
}
}
4. 리듀서
const reducer = (prevState,action)=>{
Switch(action.type){
case 'CHANGE_NAME':
return {
...prevState,
name : action.name,
};
case 'ADD_POST':
return {
...prevstate,
post:[...prevstate.posts,action.post]
};
default :
return prevState
}
};
- 스토어
const store = createStore(reducer,initState)
initState 는 디폴트파라미터역할. 초기값이 계속있는거임.
세번째 인자는 외부툴.
console.log(store.getState())
store.dispatch(changeUsername('young'))->reducer로 흘러간다.
console.log(store.getState())
store.dispatch(addpost('안녕'))
store.dispatch(addpost('배고파'))
Author And Source
이 문제에 관하여([ 07.09 ] Redux 상태관리(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@22soook00/07.09-Redux-상태관리1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)