React와 함께 쓰이는 redux라는 녀석이 있다.
이 녀석 자체만으로도 꽤 복잡해서 redux가 뭐가 어떤 원리로 사용되는지 '생활코딩'강의를 통해 공부했다.
redux는 react에 종속되는 개념이 아니나 react와 함께 잘 쓰이기 때문에 react 카테고리에 글을 쓴다.
이 강의를 분명 코딩공부 초반에도 들었었는데 그 때는 진짜 이해도 안되고 지식도 삽시간에 휘발됐다.
이번에 다시 강의를 듣는데 처음 그림부터 이해가 되고 설명은 더 이해가 되고 실전은 더더더더 이해가 되서 스스로에게 놀라워하며 들었다!
reducer 함수를 이해하게 될 줄이야. 이게 정말 공부라는 게 그런가보다. 모르는 것도 계속 접하고 다시 접하면 어느순간 띠링-하고 이해가 되는 순간이 온다. 감격스러움.. 그리고 나는 강의가 개념과 실습을 이해하는 데 효과적이고 책은 기억안나는 거를 찾아보는 용도로 쓰는 게 공부방법으로 맞는 거 같다.
Redux는 객체를 하나의 공간에서 다루고 직접 객체 접근하지 못하도록 해 immutable(불변성)을 지킨다.
state에 직접 접근하지 못하니 접근을 하도록 하는 문지기들이 있는데 상황에 따라 다른 문지기들이 state에 접근한다.
state에 뭐가 있는지 가져올 때는 'getState' 함수.
state의 값을 가지고 (dom tree를 만들어서) 화면을 그릴 때는 render 함수
state의 값을 변경할 때는 dispatch 함수
state의 값이 변하는 지 확인해서 render함수를 호출해서 변한 값으로 화면을 다시 그리게 하는 subscribe 함수
이 모든 일을 관리하는 reducer 함수
일단 store라는 공간을 만든다.
const store = Redux.createStore(reducer)
store라는 공간을 만들기 위해서 reducer 함수가 필요하다.
function reducer(state, action){
if(state === undefined){
return {
current_id:1,
array:[{title: 'blahblah', desc:'heyheyhey', id:1}]};
}
let newState;
if(action.type==='READ'){
//....
}
return newState;
}
const store = Redux.createStore(reducer);
reducer 함수는 state 객체를 반환하는데 맨 처음에 저장된 객체가 없을 때 초기 객체를 작성해서 반환한다.
그래서 store에 들어온 state 값을 확인하려면 getState()함수를 쓰면 된다.
console.log(store.getState()) // {초기 설정 객체 값}
//console.log(store)는 원하는 대로 객체 값을 보여주지 않는다.
이 state의 값을 가지고 화면을 그리는 함수가 render()이다. (render의 이름은 아무거나 상관없다.)
function render(){
let state = store.getState();
document.qeurySelector('#app').innerHtml =`
<h1>${state.title}</h1>
<div> ${state.des}</div>
<input type='button' value='delete' />
`
}
//객체안에 배열이 있고 그 배열의 값으로 화면을 그려줄 때
function render(){
let state = store.getState();
let li =''
while(i<state.array.length){
li +=`
<div>
<h1>${state.array[i].title}</h1>
<div> ${state.array[i].desc}</div>
<input type='button' value='delete' />
</div>
`
i++
}
document.qeurySelector('#app').innterHtml =`
<div>
${li}
</div>
}
//최초 1회 호출로 화면에 그려줌.
render()
render 함수 안에서 만들어 놓은 객체를 getState()로 받아와 변수 안에 넣어주고 innerHtml 에서 객체안에 있는 값을 빼서 화면을 그린다.
이제 객체의 값을 변경(추가, 삭제, 내용변경)하는 경우를 보자. 이때는 store.dispatch를 이용해 reducer를 호출한다.
input의 onclick 에 함수등록.
store는 전역객체이기 때문에 어디서든 사용 가능하다.
function render(){
let state = store.getState();
document.qeurySelector('#app').innerHtml =`
<h1>${state.title}</h1>
<div> ${state.des}</div>
<input onclick='store.dispatch({type:'DELETE', id:${state.id}})'
type='button' value='delete' />
`
}
//최초 1회 호출로 화면에 그려줌.
render()
인자로 객체를 넘겨주는데 type이라는 key는 꼭 있어야 한다.
dispatch가 실행되면 reducer 함수에 두번째 인자로 dispatch안의 객체가 넘어가고 reducer함수가 실행된다.
function reducer(state, action){
if(state === undefined){
return {초기 객체 state};
}
let newState;
if(action.type==='DELETE'){
let newArray = state.array.filter(each => each.id !== action.id)
newState = Object.assgin({}, state, { array: newArray});
}
return newState;
}
reducer 함수는 action에 들어온 객체의 type을 확인해서 type에 맞는 if 문을 찾아 if 문 안에서 새로만들어진 객체에 바뀐 객체를 담게 된다. (상황에 따라 다르게 구현됨 /create, update, delete등)
그리고 최종적으로는 바뀐 state 객체를 반환!
state가 변했으니 화면에 그리는 내용이 달라질 수도 있다. (안 그럴 수도 있다.)
화면에 내용이 달라져야한다면 (render가 다시 호출되어야 한다면) subscribe함수에 render를 등록해 놓으면 자동으로 state 변화를 감지해 render를 재호출해준다.
store.subscribe(render)
reducer함수를 얼마나 잘 구현하느냐가 핵심이다. 그로 인해 변한된 객체가 반환되니까.
redux는 상태를 관리해서 나머지 요소들이 상태를 가져다가 쓸 수 있게 해주기 때문에 다들 상태만 알고 있다면 여러 요소들끼리 결합될 필요 없이 각각의 역할만 하면 된다는 장점이 있다.

유레카 리덕스!
이미지,강의내용 출처: https://www.youtube.com/watch?v=Jr9i3Lgb5Qc&list=PLuHgQVnccGMB-iGMgONoRPArZfjRuRNVc
'Study Output for Myself > React' 카테고리의 다른 글
[React]React Query 사용후기 (1) | 2022.11.07 |
---|---|
[React]useNavigate Hook (0) | 2022.08.19 |
[react] 6 high severity vulnerabilities (0) | 2022.08.11 |
[React]useMemo & useCallBack (0) | 2022.05.30 |
react에서 Title 지정하기 (0) | 2022.05.24 |