(next.js + redux toolkit 시리즈 1) redux 설명(yotube 강의)
* RTK를 사용하는 이유는?
출처 : http://blog.hwahae.co.kr/all/tech/tech-tech/6946/
* 강의를 들은 이유 (강의 영어임, 자막 나오니까 괜찮음)
- 리덕스가 createStore에서 configureStore로 변경하라고 알림 뜸
- 이에 대해 next에서 redux toolkit을 정확이 어떻게 써야하는 지, 리덕스에 대한 개념을 다시 잡기 위해 들음
- 번역기는 위대함
* 리덕스 설명
출처 : https://www.youtube.com/watch?v=7d8w5uSMAQA&list=PLxXAf_cvJP9SAByj4a9BVySaeqzEpcOTp&index=1
▶ Store is the single common source of truth for all state value.(모든 상태값에 대한 단일 공통 source)
▶ Action is jusct a plain JS object with a mandatory key 'type' (필수키 유형이 있는 일반 JS 객체)
→ Action에서 Store로 넘어갈 때 사용 : dispatch
▶ Reducer is a function which takes in initaial state the action to be performed as parameters
and returns the upadted state. (초기 상태와 동작을 매개변수로 받아 업데이트된 상태를 반환하는 함수)
▶ One reducer manages the updation of a single slice of the store.
(하나의 리듀서는 저장소의 단일 'slice' 업데이트 관리)
Think of a 'slice' as a nest object within the store object. ('slice'를 저장소 개체 내의 중첩 객체로 생각하면 됨)
▶ Data is divided into multiple 'slice'. (데이터는 여러 'slice'로 나뉨)
▶ Each slice has its own reducer. (각 'slice'는 자신의 reducer 가짐)
[store.js]
const { createStore } = require("redux");
const initState = {
counter: 0,
name: "john",
};
const reducer = (state = initState, action) => {
if (action.type === "INCREMENT") {
state.counter = state.counter + 1;
return state;
}
if (action.type === "DECREMENT") {
state.counter = state.counter - 1;
return state;
}
if (action.type === "UPDATE_NAME") {
state.name = action.payload.name;
return state;
} else return state;
};
const store = createStore(reducer);
module.exports = store;
[main.js]
const store = require("./store");
store.subscribe(() => {
console.log(store.getState());
});
const increment = {
type: "INCREMENT",
};
const updateName = {
type: "UPDATE_NAME",
payload: {
name: "jane",
},
};
const decrement = {
type: "DECREMENT",
};
store.dispatch(increment); //{ counter: 1, name: 'john' }
store.dispatch(increment); //{ counter: 2, name: 'john' }
store.dispatch(updateName); //{ counter: 2, name: 'jane' }
store.dispatch(decrement); //{ counter: 1, name: 'jane' }
출처 : https://www.youtube.com/watch?v=b5udK0GEpyk&list=PLxXAf_cvJP9SAByj4a9BVySaeqzEpcOTp&index=2
* combineReducer
▶ 여러 개의 정의한 리듀서 모듈을 결합한 것
[store.js]
▶ 기존의 reducer이외의 auth라는 리듀서 생성
▶ combineReducer로 둘을 결합함
const { createStore, combineReducers } = require("redux");
const initState = {
counter: 0,
name: "john",
};
const reducer = (state = initState, action) => {
if (action.type === "INCREMENT") {
state.counter = state.counter + 1;
return state;
}
if (action.type === "DECREMENT") {
state.counter = state.counter - 1;
return state;
}
if (action.type === "UPDATE_NAME") {
state.name = action.payload.name;
return state;
} else return state;
};
const initAuth = {
loggedIn: false,
username: "",
};
const auth = (state = initAuth, action) => {
if (action.type === "LOGIN") {
state.loggedIn = true;
return state;
}
if (action.type === "LOGOUT") {
state.loggedIn = false;
return state;
}
if (action.type === "SET_USERNAME") {
state.username = action.payload.username;
return state;
} else return state;
};
const rootReducer = combineReducers({
reducer,
auth,
});
const store = createStore(rootReducer);
module.exports = store;
[main.js]
const store = require("./store");
store.subscribe(() => {
console.log(store.getState());
});
const increment = {
type: "INCREMENT",
};
const login = {
type: "LOGIN",
};
const logout = {
type: "LOGOUT",
};
const setUsername = {
type: "SET_USERNAME",
payload: {
username: "john_123",
},
};
const updateName = {
type: "UPDATE_NAME",
payload: {
name: "jane",
},
};
const decrement = {
type: "DECREMENT",
};
store.dispatch(increment);
//{
// reducer: { counter: 1, name: 'john' },
// auth: { loggedIn: false, username: '' }
//}
store.dispatch(updateName);
//{
// reducer: { counter: 1, name: 'jane' },
// auth: { loggedIn: false, username: '' }
//}
store.dispatch(login);
// {
// reducer: { counter: 1, name: 'jane' },
// auth: { loggedIn: true, username: '' }
//}
store.dispatch(setUsername);
// {
// reducer: { counter: 1, name: 'jane' },
// auth: { loggedIn: true, username: 'john_123' }
//}
출처 : https://www.youtube.com/watch?v=PHd94oFAmwQ&list=PLxXAf_cvJP9SAByj4a9BVySaeqzEpcOTp&index=3
* state에다가 바로 적용하는 것이 아닌 복사 후 적용해야 함
▶ 이유 : We will use redux store values as our React state and hence they cannot be directly mutated.
To archieve that reducers are made 'pure'
(redux 저장소 값을 React 상태로 사용하므로 직접 변경할 수 없습니다.
리듀서가 '순수'하게 만들어졌다는 것을 보관(기록)하기 위해서입니다.)
[store.js]
▶ ...으로 복사(stateCopy)
▶ main.js는 위의 2강과 동일
const { createStore, combineReducers } = require("redux");
const initState = {
counter: 0,
name: "john",
items: [],
};
const reducer = (state = initState, action) => {
const stateCopy = { ...state, items: [...state.items] };
if (action.type === "INCREMENT") {
stateCopy.counter++;
} else if (action.type === "DECREMENT") {
stateCopy.counter--;
} else if (action.type === "UPDATE_NAME") {
stateCopy.name = action.payload.name;
} else if (action.type === "ADD_ITEM") {
stateCopy.items.push(action.payload.item);
}
return stateCopy;
};
const initAuth = {
loggedIn: false,
username: "",
};
const auth = (state = initAuth, action) => {
const stateCopy = { ...state };
if (action.type === "LOGIN") {
stateCopy.loggedIn = true;
} else if (action.type === "LOGOUT") {
stateCopy.loggedIn = false;
} else if (action.type === "SET_USERNAME") {
stateCopy.username = action.payload.username;
}
return stateCopy;
};
const rootReducer = combineReducers({
reducer,
auth,
});
const store = createStore(rootReducer);
module.exports = store;