3주차 - 리덕스, 리덕스를 통한 리액트 상태관리
본문 바로가기
항해 중/3주차 리액트 기초반

3주차 - 리덕스, 리덕스를 통한 리액트 상태관리

by 은돌1113 2021. 11. 18.

리덕스란?

: 전역 상태(데이터) 저장소입니다.

 

https://velog.io/@gunu/%EC%A0%84%EC%97%AD%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC

 

전역상태관리

전역상태관리란 말하는바 그대로 전역에서 상태를 관리한다는 의미입니다.리액트에서는 상위에서 하위로 상태값을 전달하여 상태를 관리하게 되어있습니다.그러나 위와 같이 컴포넌트가 분리

velog.io

 

1) 상태관리가 왜 필요할까?

 

[복습하자!]

 

저희가 만들었던 버킷리스트를 되짚어봅시다!

지금은 App.js에서 리스트 항목 배열을 넣어두고, props로 넘겨주고 있습니다. 그리고 추가하기 버튼도 App.js에 있고요. 만약에, 우리가 이 추가하기 버튼과 텍스트 영역을 AddListItem 컴포넌트를 만들어 분리하고 싶다면 어떻게 해야할 것 같나요? 파일을 만들고 코드를 만들면 될까요? 그렇게 하면 추가하기 버튼을 눌렀을 때 정말 App 컴포넌트의 state를 수정할 수 있을까요?

 

→ 아니요!!!, 자식 컴포넌트는 부모 컴포넌트의 state를 맘대로 조작할 수 없어요.

→ 왜냐면 데이터는 부모에서 자식으로 흐르게 하기로 했으니까요. (데이터는 단방향으로!)

그런데 만약에, App 컴포넌트와 AddListItem 컴포넌트가 같은 데이터 저장소를 본다면(구독하고 있다면) 어떨까요?

→ AddListItem에서 추가를 하면 App이 보고 있는 데이터도 같이 추가가 되겠죠!

 

또는 부모 컴포넌트가 있고, 1~4번까지의 자식 컴포넌트가 있는 데 부모 컴포넌트의 state 값을 가장 아래에 있는 4번 자식 컴포넌트가 props로 받아야 한다면 1~3번 자식 컴포넌트는 필요하지 않은 상태(데이터)를 넘겨줘야 하기 때문에 쓰지 않는 데이터를 가지고 한다. 이런 경우를 props drilling이라고 한다.

이럴 경우 코드가 더러워지고 유지보수가 안좋아 진다.

 

리덕스는 여러 컴포넌트가 동일한 상태(데이터)를 보고 있을 때 유용합니다!!

또, 데이터를 관리하는 로직을 컴포넌트에서 빼면, 컴포넌트는 정말 뷰만 관리 할 수 있기 때문에

코드가 깔끔 해지고, 유지보수도 좋아집니다.

 

2) 상태관리 흐름을 알아보자!

 

★ 거의 모든 라이브러리들이 동일한 흐름을 가진다!

(1) 전역으로 볼 수 있는 어떤 데이터가 있다.

(2) 그 데이터를 참조하고 싶은 애들이 있고, 참조하는 애들 중에서는 수정하고 싶어하는 애들이 있다.

(즉, 참조하는 애와 수정하는 애가 있다.)

(3) 바뀐 값을 모두가 보게 해줘야 한다.

 

[상태관리 흐름도]

딱 4가지만 알면 됩니다.

store, action, reducer 그리고 component! 아주 큰 흐름만 잘 파악해도 굳굳!!

(1) 리덕스 Store를 Component에 연결한다.

(2) Component에서 상태 변화가 필요할 때 Action을 부른다.

(3) Reducer를 통해서 새로운 상태 값을 만들고,

(4) 새 상태값을 Store에 저장한다.

(5) Component는 새로운 상태값을 받아온다. (props를 통해 받아오니까, 다시 랜더링 되겠죠?)

 

3) 리덕스 패키지 설치

 

리덕스는 아주 흔히 사용하는 상태관리 라이브러리입니다.

전역 상태관리를 편히 할 수 있게 해주는 고마운 친구죠!

 

- 리덕스 패키지 설치하기

yarn add redux react-redux

-> redux : 말 그대로 redux를 설치하는 것

-> react-redux : react에서 redux를 편리하게 사용 할 수 있도록 도와주는 패키지

redux는 react만 사용하는 것이 아니라 프론트엔드 프레임워크 / 라이브러리에서 사용 할 수 있습니다.

 

+ 공식 문서

(자세하게 잘 나와 있기 때문에 자주 이용하면 좋다.)

https://ko.redux.js.org/introduction/getting-started/

 

Redux 시작하기 | Redux

소개 > 시작하기: Redux를 배우고 사용하기 위한 자료

ko.redux.js.org

 

- 리덕스 개념과 용어

: 리덕스는 데이터를 한 군데 몰아넣고, 여기저기에서 꺼내볼 수 있게 해주는 친구입니다. 아래 용어들은 리덕스의 기본 용어인데, 여러분이 키워드 삼기 좋은 용어들이에요. 앞으로 자주 볼 단어들이니 미리 친해집시다!

 

(1) State (상태값)

: 리덕스에서는 저장하고 있는 상태값("데이터"라고 생각하셔도 돼요!)를 state라고 불러요.

딕셔너리 형태({[key]: value})형태로 보관합니다.

 

(2) Action

("나 이 데이터 수정 할래!"에 대한 내용을 담고 있다.)

: 상태에 변화가 필요할 때(=가지고 있는 데이터를 변경할 때) 발생하는 것입니다.

// 액션은 객체예요. 이런 식으로 쓰여요. type은 이름같은 거예요! 저희가 정하는 임의의 문자열을 넣습니다.
{type: 'CHANGE_STATE', data: {...}}

 

(3) ActionCreator

("나 어떤 데이터를 어떻게 바꿀래!"에 대한 내용을 담고 있다.)

: 액션 생성 함수라고 합니다. 액션을 만들기 위해 존재하는 함수

//이름 그대로 함수예요!
const changeState = (new_data) => {
// 액션을 리턴합니다! (액션 생성 함수니까요. 제가 너무 당연한 이야기를 했나요? :))
	return {
		type: 'CHANGE_STATE',
		data: new_data
	}
}

 

(4) Reducer

(데이터를 실제로 바꾸는 곳)

: 리덕스에 저장된 상태(=데이터)를 변경하는 함수입니다.

우리가 액션 생성 함수를 부르고 → 액션을 만들면 → 리듀서가 현재 상태(=데이터)와 액션 객체를 받아서

→ 새로운 데이터를 만들고 → 리턴해줍니다.

// 기본 상태값을 임의로 정해줬어요.
const initialState = {
	name: 'mean0'
}

function reducer(state = initialState, action) {
	switch(action.type){

		// action의 타입마다 케이스문을 걸어주면, 
		// 액션에 따라서 새로운 값을 돌려줍니다!
		case CHANGE_STATE: 
			return {name: 'mean1'};

		default: 
			return false;
	}	
}

 

(5) Store

(리듀서를 포함해서 상태값을 가져 오거나 바꾸거나 하는 내장함수들을 가지고 있다고 생각하면 된다.)

: 우리 프로젝트에 리덕스를 적용하기 위해 만드는 거예요! 스토어에는 리듀서, 현재 애플리케이션 상태, 리덕스에서 값을 가져오고 액션을 호출하기 위한 몇 가지 내장 함수가 포함되어 있습니다. 생김새는 딕셔너리 혹은 json처럼 생겼어요. 내장함수를 어디서 보냐구요? → 공식문서에서요! 😉

 

(6) Dispatch

(Reducer에 "나 이거 바꿔줘"라고 수정을 요청하는 역할)

: 액션을 발생 시키는 역할을 합니다.

// 실제로는 이것보다 코드가 길지만, 
// 간단히 표현하자면 이런 식으로 우리가 발생시키고자 하는 액션을 파라미터로 넘겨서 사용합니다.
dispatch(action);

 

+ 몰라도 되는, 하지만 알면 재미있는 이야기 리덕스는 사실, 리액트와 별도로 사용할 수 있는 친구입니다.

상태관리를 위해 다른 프론트엔드 프레임워크/라이브러리와 함께 쓸 수 있어요.

 

- 리덕스의 3가지 특징

 

(1) Store는 1개만 쓴다.

: 리덕스는 단일 스토어 규칙을 따릅니다. 한 프로젝트에 스토어는 하나만 씁니다.

(단일 스토어에 리듀서는 여러 개일 수 있다.)

 

(2) store의 state(데이터)는 오직 action으로만 변경할 수 있다!

("나 이거 바꿔줘"라고 Reducer에 요청하고 바꾸는 건 Reducer에게 맡겨야 한다.)

 

: 리액트에서도 state는 setState()나, useState() 훅을 써서만 변경 가능했죠!

데이터가 마구잡이로 변하지 않도록 불변성을 유지해주기 위함입니다.

불변성 뭐냐구요? 간단해요! 허락없이 데이터가 바뀌면 안된단 소리입니다!

조금 더 그럴 듯하게 말하면, 리덕스에 저장된 데이터 = 상태 = state는 읽기 전용입니다.

 

그런데... 액션으로 변경을 일으킨다면서요? 리듀서에서 변한다고 했잖아요?

→ 네, 그것도 맞아요. 조금 더 정확히 해볼까요!

가지고 있던 값을 수정하지 않고, 새로운 값을 만들어서 상태를 갈아끼웁니다!

즉, A에 +1을 할 때, A = A+1이 되는 게 아니고, A' = A+1이라고 새로운 값을 만들고 A를 A'로 바꾸죠.

 

(3) 어떤 요청이 와도 리듀스는 같은 동작을 해야 합니다.

: 리듀서는 순수한 함수여야 한다는 말입니다. 순수한 함수라는 건,

 

- 파라미터 외의 값에 의존하지 않아야 한다.

(전역 변수에서 값을 가져와서 사용하면 안되고 무조건 액션에서 넘어온 파라미터 값만 사용해야 한다.)

- 이전 상태는 수정하지(=건드리지) 않는다. (변화를 준 새로운 객체를 return 해야합니다.)

(State를 직접적으로 건드리면 안된다, 새로운 State만 반환 해야 한다.)

- 파라미터가 같으면, 항상 같은 값을 반환

(예를 들어 랜덤 함수를 사용했을 때는 1을 받았는 데 랜덤 함수 때문에 매번 다른 값이 나오면 순수한 함수가 아니다.)

- 리듀서는 이전 상태와 액션을 파라미터로 받는다.

댓글