[React-Redux] [1.5] redux-toolkit까지 간단 요약
이 챕터에서는 유데미가 아닌 노마드코더에서 배웠던 redux 무료 기본 강의를 요약해본 것입니다.
노마드코더: 초보자를 위한 redux
코드는 여기서: 제 github repository
다음 챕터 2부터는 다시 유데미 강의 기반으로 react-redux를 깊게 파고 들어가 정리해볼게요!
vanilla-redux 정리 : pure redux
1. Counter
store: data를 넣는 곳, 즉 state. data를 넣을 수 있는 장소를 생성함
state: application 내에서 변하는 데이터
createStore: store를 생성. reducer 함수가 인자로 필요함
createStore.getState() : 데이터를 받음
reducer: 데이터를 변경하는 함수. 오직 이 곳에서만 데이터를 변경할 수 있음. return 값이 application의 데이터가 됨. reducer에서 state를 초기화할 수 있음.
-> 매개변수 : currentState, action
Action: reducer에서 어떤 걸 보고 state를 변경할까? action! reducer의 두 번쨰 매개변수. 객체여야 한다(type key를 가져야 함).
-> action 전달하여 reducer 실행시키기 : store.dispatch(action)
subscribe: store 안에 있는 변화들을 알 수 있게 해줌
정리
- 데이터를 저장할 store를 state를 변경하는 곳인 reducer
- 이를 인자로 한 createStore(reducer) 즉, "store"를 받아 저장
- store.dispatch(action) 메서드를 호출하면 reducer에서 매개변수로 받은 이 action 내용에 따라 state 변경
- store에 저장된 state가 변경될 때마다 store.subscribe(함수)에 함수가 실행됨.
2. ToDoList
- 다른 곳에 갔다가 돌아와도 데이터가 유지되길 바람.
-
action 객체에 들어갈 프로퍼티는 type 뿐만 아니라 다른 것도 추가 가능함. 사용할 데이터를 넣을 수 있음
-
mutate(변형) state 절대 쓰지 말자: 이유
-> 상태를 수정하는 게 아니라, 새로운 객체 state를 return해야 함.// reducer 내부 // add state.push(action.text); // X return [...state, { text: action.text }]; // O // delete return state.filter((toDo) => action.id !== toDo.id);
React-Redux 정리
1. React에서 Redux 시작하기
1) 설치
npm i react-redux
2) 시작하기
- store, reducer: store 파일 내부에 작성(단 `export default store;` 해주자)
- 준비: 구독할 컴포넌트를 등록하기 위해 최상단 index.js에 App을 감싸는 Provider 등록. store를 provider 속성으로 import
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
- mapStateToProps(getState 개념): state를 사용하고 싶은 컴포넌트에서 `export default connect(mapStateToProps)(컴포넌트)`
- 함수(문서 상 이름은 mapStateToProps): redux state, 해당 텀포넌트 props를 가져옴. return 값(꼭 state 자체일 필요는 없음)은 해당 컴포넌트의 prop이 됨
function mapStateToProps(state, ownProps) {
// store의 state, 컴포넌트 내부 props
return { toDos: state };
}
export default connect(getCurrentState)(Home);
- mapDispatchToProps(dispatch(action) 개념): dispatch를 사용하고 싶은 컴포넌트에서 `export default connect(null,mapDispatchToProps)(컴포넌트)`
- 함수(문서 상 이름은 mapDispatchToProps): dispatch 함수, 해당 텀포넌트 props를 가져옴. return 값(꼭 dispatch 자체일 필요는 없음)은 해당 컴포넌트의 prop이 됨
- 컴포넌트 내부에서 dispatch를 쓰는 것을 피하는 게 깔끔하다고 함.
- deletToDo도 마찬가지
// store.js
export const actionCreator = {
addToDo,
deleteToDo,
};
// Home.js
function mapDispatchToProps(dispatch, ownProps) {
return {
addToDo: (text) => dispatch(actionCreator.addToDo(text)),
};
}
// Home 컴포넌트
function Home({ toDos, addToDo }) {...}
// mapStateToProps, mapDispatchToProps 둘 다 필요한 경우 export
export default connect(mapStateToProps, mapDispatchToProps)(컴포넌트);
// deleteToDo
// ToDo,js
function mapDispatchToProps(dispatch, ownProps) {
return {
onBtnClick: () => dispatch(actionCreator.deleteToDo(ownProps.id)),
};
}
2. Redux toolkit 시작하기
- 기존 react-redux의 문제점: 코드가 너무 길다..
- 적은 양의 코드만으로 redux 기능을 사용할 수 없을까?
- redux-toolkit 설치
npm i @reduxjs/toolkit
-
createAction: action을 정의하지 않아도 된다.
- 대신 reducer에 전달된 action에는 type과 payload(데이터)만 있다.
- 작성법:
action = createAction(type)
// store.js
import { createAction } from "@reduxjs/toolkit";
const addToDo = createAction("ADD"); // addToDo.type === "ADD"
const deleteToDo = createAction("DELETE"); // deleteToDo === "DELETE"
// 아래는 전과 동일
export const actionCreator = {
addToDo,
deleteToDo,
};
// home.js
function mapDispatchToProps(dispatch, ownProps) {
return {
addToDo: (text) => dispatch(actionCreator.addToDo(text)),
// reducer에서 action.payload === text
};
}
-
createReducer: reducer 대체
- switch문 등등의 코드 단축
- state를 mutate하기 쉬워짐(원래 안되었음)
- state 변경하는 법 2가지
- 새로운 state를 return(꼭 새로운 값이어야 함)
- state를 mutate(return 필요없음)
const getLocalToDos = JSON.parse(localStorage.getItem("toDos"));
const reducer = createReducer(getLocalToDos || [], {
[addToDo]: (state, action) => {
const newToDo = { text: action.payload, id: Date.now() };
state.push(newToDo);
localStorage.setItem("toDos", JSON.stringify(state));
},
[deleteToDo]: (state, action) => {
const filteredToDos = state.filter(
(toDo) => toDo.id !== action.payload
);
localStorage.setItem("toDos", JSON.stringify(filteredToDos));
return filteredToDos;
},
});
- configureStore: createStore 대체
- 기능: createStore + Redux DevTools로 코드 리팩토링 용이
- 사용법
const store = configureStore({ reducer });
- createSlice: reducer, action을 모두 축약!(캡슐화)
- createSlice가 return하는 것: action, reducer
// console.log(toDos)해보면
{name: 'toDosReducer', actions: {…}, caseReducers: {…}, reducer: ƒ}
actions: {add: ƒ, remove: ƒ}
caseReducers: {add: ƒ, remove: ƒ}
name: "toDosReducer"
reducer: ƒ (state, action)
// 예시
const toDos = createSlice({
name: "toDosReducer",
initialState: getLocalToDos || [],
reducers: {
add: (state, action) => {
const newToDo = { text: action.payload, id: Date.now() };
state.push(newToDo);
localStorage.setItem("toDos", JSON.stringify(state));
},
remove: (state, action) => {
const filteredToDos = state.filter(
(toDo) => toDo.id !== action.payload
);
localStorage.setItem("toDos", JSON.stringify(filteredToDos));
return filteredToDos;
},
},
});
export const { add, remove } = toDos.actions;
export default configureStore({ reducer: toDos.reducer });
Author And Source
이 문제에 관하여([React-Redux] [1.5] redux-toolkit까지 간단 요약), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kimyoungyin/React-Redux-1.5-redux-toolkit까지-간단-요약저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)