기록 전체보기/React
Redux 사용하기
Kyoo130
2022. 7. 3. 22:18
본 게시글은 개인 공부를 하면서 기록 목적으로 작성한 내용입니다.
잘못된 내용이 있다면 제보 부탁드립니다. 🙇♂️
1. redux를 사용하는 이유
리액트의 내장 함수인 useState를 사용하여 자식 컴포넌트에 state를 전달하려면 props로 내려야 한다.
만약, state가 자식의 자식의 자식에서 사용한다면 props를 내리고 또 내리고를 반복해야 하는 불편함이 발생한다.
redux는 전역 상태 관리를 편히 할 수 있게 해주는 라이브러리로 컴포넌트에 종속되지 않고,
상태 관리를 컴포넌트 밖에서 사용할 수 있다.
프로젝트 루트 레벨에서 store라는 곳에 state를 저장하고, 모든 컴포넌트는 store에 구독을 하면서
state와 그 state를 바꾸는 함수를 어느 위치에 있든 상관 없이 상태를 받을 수 있게 된다.
2. redux의 기본 원리
- 리덕스 Store를 Component에 연결한다.
- Component에서 상태 변화가 필요할 때 Action을 부른다.
- Reducer를 통해서 새로운 상태 값을 만든다.
- 새 상태값을 Store에 저장한다.
- Component는 새로운 상태값을 받아온다.
3. redux 개념과 용어
Action
- 상태에 어떠한 변화가 필요하면 액션(action) 이란 것이 발생한다.
- 액션은 반드시 Type 필드를 가지고 있어야 하며, 이 값을 액션의 이름이라고 한다.
ActionCreator
- 액션 생성 함수라고 부르며, 액션을 만들기 위해 사용한다.
- 어떤 변화를 일으켜야 할 때마다 액션 객체를 만들어야 하는데 액션 생성 함수를 만들어 이를 관리한다.
Reducer
- reducer는 store에 들어갈 state와 함수를 정의하는 곳이다.
- 기본적으로 수순 함수로 코딩하고, 불변성을 지켜야 한다.
- 리덕스에 저장된 데이터(state)를 변경하는 함수로 리듀서가 현재 상태와 액션 객체를 받아서 새로운 데이터를 만들고 돌려준다.
- 불변성이란?
- 허락없이 데이터가 바뀌면 안된다는 의미로 리덕스에 저장된 데이터(state)는 마구잡이로 변하지 않도록 불변성을 유지해주어야 한다.
Store
- 프로젝트에 리덕스를 적용하기 위해 만드는 것으로 스토어에는 리듀서, 현재 애플리케이션 상태, 리덕스에서 값을 가져오고 액션을 호출하기 위한 몇 가지 내장 함수가 포함되어 있다.
- 리덕스는 단일 스토어 규칙을 따르기 때문에 한 프로젝트에 스토어는 하나만 쓸 수 있다.
- store의 데이터(state)는 오직 action으로만 변경할 수 있다.
dispatch
- 디스패치는 액션을 발생 시키는 역할을 하는 스토어의 내장 함수이다.
4. 프로젝트 사용 예제
- src/redux/modules/techInfo.js
// 액션 생성
const CREATE = 'techInfo/CREATE';
const DELETE = 'techInfo/DELETE'
// 초기값 설정
const initialState = {
list: [
{
id: 0,
author: "글쓴이A",
title: "0번째 게시글입니다.",
category: "HTML",
url: "http://www.naver.com",
content: "유용한거 같아서 공유합니다.",
created_date: new Date().toLocaleString(),
},
{
id: 1,
author: "글쓴이B",
title: "1번째 게시글입니다.",
category: "CSS",
url: "http://www.google.com",
content: "유용한거 같아서 공유합니다.",
created_date: new Date().toLocaleString(),
},
{
id: 2,
author: "글쓴이C",
title: "3번째 게시글입니다.",
category: "React",
url: "http://velog.io",
content: "react dom에 관한 글입니다.",
created_date: new Date().toLocaleString(),
},
],
};
// 액션 생성 함수
export function createTechInfo(techInfo) {
return {type: CREATE, techInfo: techInfo};
}
export function deleteTechInfo(techInfo_id) {
return {type: DELETE, techInfo_id};
}
//리듀서
export default function reducer(state = initialState, action = {}) {
switch (action.type) {
case "techInfo/CREATE": {
const new_techInfo_list = [...state.list, action.techInfo];
return {list: new_techInfo_list}
}
case "techInfo/DELETE": {
const new_techInfo_list = state.list.filter((l, idx) => {
return parseInt(action.techInfo_id) !== idx;
});
return {list: new_techInfo_list}
}
default: return state;
}
}```
- src/redux/configStore.js
import { createStore, combineReducers } from "redux";
import techInfo from "./modules/techInfo";
const rootReducer = combineReducers({ techInfo });
const store = createStore(rootReducer);
export default store;