Redux 이해하기(1)

김하은·2022년 12월 11일
2

Project-Study

목록 보기
6/7
post-thumbnail

프로젝트를 하면서 어떤 상태관리 라이브러리를 사용할까 고민 하였는데
redux가 꽤나 복잡해 보였다. 따라, 조금더 사용하기 쉽고 가벼운 recoil 을 이용하여 프로젝트를 하였지만, 상태관리 라이브러리의 근본인 redux 에 대해 조금더 자세히 공부하고 싶다는 간지러움이 남아있어 정리해 보았다. 이 강의는 유튜브[생활코딩] 님의 영상을 보고
이해한 바탕으로 정리한 글 이다.


✅리덕스는 ?

Redux는 "액션"이라는 이벤트를 사용하여 애플리케이션 상태를 관리하고 업데이트하기 위한 패턴 및 라이브러리입니다. 상태가 예측 가능한 방식으로만 업데이트될 수 있도록 하는 규칙과 함께 전체 애플리케이션에서 사용해야 하는 상태에 대한 중앙 집중식 저장소 역할을 합니다.
-Redux 공식 홈페이지 -

즉 , 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너 이다.


✅소프트웨어를 개발할때 가장 주의해서 생각해야할 것이 "복잡성" 이다.
복잡성이 위험한 이유는 눈에 보이지 않기 때문이다. 따라, 자연스레 우리는 코드의 복잡성을 낮추고 싶어한다.

📝이러한 복잡성을 낮추면 더욱 복잡하면서도 좋은 애플리케이션을 만들수 있다.

"Redux" 는 복잡성을 낮춰서 우리의 코드가 어떤 결과를 가져올지 예측 가능하게
만들어주는 🛠도구🪓이다.


🤔과연 리덕스는 어떤식으로 이뤄지고 있는걸까?

🔥Redux 의 가장 중요한 특징"단 하나의 상태를 갖는다" -> SST(Single Source of Truth)
📍하나의 개체 (한곳의 data를 중앙집중 관리한다.)
(여기서 말하는 data = 우리가 갖고 있는 data 라 생각하면 된다.)

ex) 갖고 있는 content data 들의 모양

state ={
	contents{
 	 {id:1, title: ''}
	 {id:2, title: ''}
	}
}

ex) 특정 데이터를 선택 했을때

state ={
	contents{
 	 {id:1, title: ''}
	 {id:2, title: ''}
	}
    selected_id2
}

-> 이렇게 상태를 바꿈에 따라서 우리 애플리케이션의 모습이 바뀐다.

Redux는 두가지의 컨셉을 갖고 있는데

✅첫번째
-> 단 하나의 state 를 유지하는것 을 통해서 애플리케이션의 복잡성을 낮춘다.
✅두번째
-> 데이터 상태는 중요하기 때문에 따로 분리되어서 데이터 정보를 함부로 수정할수 없게 하고,
함수를 통해서만 수정할수 있게 끔 한다.

여기 두번째의 컨셉에 해당 되는 함수가 바로 "dispatch" , "reducer" 이다.
데이터 값에 대해 변경이 필요하면 redux 가 확인후 최종 변경값을 반영한다.

또한, 데이터를 가져올때도 get state 를 통해서 가져올수 있다.


Redux 는

📍 외부에서 직접적으로 데이터를 변경, 가져올수 없게끔 하여 예기치 않게 state 값이 바뀌는것을 사전에 차단한다.

📍 state 값이 바뀔때마다 state 에 데이터를 사용하는 여러 기능에게 바뀐 데이터 값을 알려주는 역할을 한다.

📍 각각의 state 값을 생성할때 원본을 바꾸는게 아닌, 원본을 복제 하고 복제한 데이터를 수정해서 그것을 새로운 원본으로 만드는 방식이다.
따라, 각각의 상태값 변화가 다른 데이터들에게 영향을 주지 않고 독립된 형태를 유지 할수 있다.


더 나아가, redux 를 사용하면 디버거를 통해 현재 상태뿐만 아니라, 이전의 상태 시점 가지 볼수 있어서 문제 해결에 큰 도움이 된다.

또한,redux 의 특성을 이용해서 (react-hot-loader) 을 이용할수 있는데
코드가 변경될 때마다 페이지가 새로고침없이 업데이트 된다.
(data 가 변경되지 않고 남아 있는다. 불 필요한 입력 작업이 필요 없음)


🔥 redux 의 핵심!!! "store"

store -> 정보가 저장 되는 곳 현재 글 목록, 현재 선택한 글 목록
이 store 안에 다 저장 되는 것이다.

store 안에는 실제 정보가 state 안에 저장 된다.
❌state 안에 정보를 직접 적으로 변경하지 않는다.


✅ Redux 시작하기

🚩 1. store 을 만들면서 제일 먼저 "reducer" 라는 함수를 만든다.
ex)

function reducer(oldState, action){
	//....
}
var store = Redux.createStore(reducer);

-> Redux.createStore
리덕스에 createStore 을 하게 되면, store 가 생성이 되고 이 store 을 생성할땐
꼭 인자값을 (reducer) 주어야 한다.
-> 이 reducer은 function 함수

🚩 2. 그 다음은 render 라는 함수 이다.
render = UI 를 만들어주는 역할을 한다.
(redux 라는 것과는 상관없기 때문에 store 에 포함되어 있지 않음.)

function render(){
	var state = store.getState();
  //....
  docment.querySelector('#app').innerHTML= `
<h1>WEB</h1>
	....
`
}

-> render() 의 함수는 위와 같은 로직으로 되어있다.
store.getState(); 를 사용하여 state 값을
가져올수 있는것 .
= state 값을 참조해서 직접적인 UI 를 그릴수 있는 역할을 한다.

🚩 3. state 에 있는 정보를 직접적으로 변경할수 없기 3가지를 통해 변경하거나, 데이터를 가져올수 있다
(dispatch, subscribe, getState)


🤔생각해보기

-> state 값이 변경 될때 render함수를 자동적으로 호출하면 편하지 않을까?

😮 바로 이 부분에 대한 역할을 해주는 함수가 구독 이라는 뜻의 "subscribe" 이다.

  • render 함수를 "subscribe" 에 등록하는 함수로직
store.subscribe(render);

-> store 안 subscribe 에 render 함수를 등록 시켜 놓으면 state 값이 바뀔때마다 render 함수가 호출되면서 UI가 새롭게 갱신된다.


✅Redux 의 동작 원리.

submit 버튼을 누르면 값이 추가 되는 로직을 생각해보자
ex)

<form onsubmit="
	//...
	store.dispatch({type:'create', payload:{title:title, desc:desc}});
">

-> 이 로직을 보면 type이 'create' 로 객체를 보내는데 (:{title:title, desc:desc})
이 객체를 'action' 이라고 하고 , 이 action -> dispatch 에게 전달이 된다.


✅dispatch 란?

-> 두가지의 일을 한다.
🚩 1. reducer 을 호출해서 state 값 을 바꾼다.
그리고 이 작업이 끝난후
🚩 2. subscribe 를 통해
render 함수를 호출하여 화면이 바뀌게 끔 한다.

dispatch 는 reducer 에게 2개의 값을 전달한다.
한개는 현재의 state 값, 다른 한개는 action 값에 대한 객체 를 전달한다.

이를 코드로 나타내보면
ex)

function reducer(state, action){
	if(action.type === 'create'){
    	var newContents = oldState.contents.concat();
        var newMaxId = oldState.maxId+1;
       newContents.push({id:newMaxId,title:action.parameter})
       return Object.assign({}, state, {
         contents:newContents,
         maxId:newMaxId,
         mode:'read'
         selectedId:newMaxId
    });

};

-> 파라미터에 현재 상태의 (state 와 action) 값이 dispatch에 의해 전달이 된다.
if (action 의 type이 === create) 이니까
reducer 안에 써져 있는 로직들은 action값이다.
여기서 return을 해주는 값은 새로운 state 의 값이다.
즉, reducer 은 state를 입력 값으로 받고,
action을 참조해서 새로운 state 값을 만들어내서 return 해주는 state 를 가공하는 가공자 역할을 한다.

reducer 가 return 해주는 값이 새로운 state 값이 된다.
state값이 변경이 되면 render가 다시 호출 되야 한다.

이것을 dispatch가 해주는데 subscribe 에 등록되어 있는 함수들을 다 호출 한다.
그러면 render 가 호출 되면서 getState 로 state 값을 가지고 올수 있다.

state의 값을 가져오면 render 가 화면의 UI를 다시 그려준다.
이것이 redux 의 흐름이다.


🔥중요한것은
1. state로 화면에 그려준다
2. state에 직접 전달할수 없기 때문에, getState 를 통해서 값을 가져오고
dispatch 를 통해 값을 변경시키고 subscribe 통해 값이 변경 되었을때 구동될 함수들을 등록
3. reducer 를 통해서 state 값을 변경한다.


🍀요약 정리
1. store 을 만들면서 제일 먼저 "reducer" 라는 함수를 만든다.
2. 그 다음 render 라는 함수를 만든다. (render = UI 를 만들어주는 역할을 한다.)
3. getState를 사용하여 state 값을 가져올수 있다.
4. render 를 subscribe 에 등록하여, state 값이 바뀔때마다 render 함수가 호출되게 한다.
5. 외부에서 상태가 일어나면 action 이 일어나고 이 action -> dispatch전달 -> reducer 호출 -> state 값 변경 이 일어난다.
6. state 변경 후 -> dispatch가 subscribe 를 통해 render 함수를 호출 -> getState 로 state 값을 가지고 와 render 가 화면을 다시 그려준다.

profile
꾸준함을 이기는것은 없다

0개의 댓글