여기까지 오기 전에 가상DOM 이름만 몇 번 접했을 때는 너무 어렵고 복잡한 개념일 거라고 생각했는데, 강의를 듣고 공부해보고 나니 흥미로운 개념이라는 생각이 들었다. 이런 걸 처음 고안해 낸 사람은 그야말로 천재다🥹
가상DOM은 실제 DOM과 구조가 동일한 형태의 복사본으로, 객체 형태로 메모리에 저장된다. 실제 DOM을 조작하는 것보다 javascript 객체를 변경하는 작업이 더 가볍기 때문에 더 빠르게 조작을 수행할 수 있다.
diffing
state가 변경될 때 가상DOM을 비교하여 어느 엘리먼트에 변화가 일어났는지 파악한다.
reconciliation
파악이 끝나면 해당 부분만 실제 DOM에 적용시킨다. 변경 사항은 Batch Update된다. --> 5개의 변경사항이 있어도 1회만 렌더링된다.
전역 상태관리 라이브러리. 중앙 state 관리소 역할을 하는 패키지(라이브러리)이다. Redux를 사용하면 State를 공유할 때 부모-자식 관계가 아니어도 되기 때문에 의미 없는 drilling을 거치지 않아도 된다.
특정 컴포넌트 안에서만 필요한 state는 지역 상태(Local state)로 관리하고, 어디서든 접근/제어하고 싶은 state는 전역 상태(Global state)로 관리한다.
1. 리덕스 패키지 설치하기
npm i redux react-redux
yarn add redux react-redux
2. ./redux / config / configStore.js
중앙 state 관리소를 아래처럼 기본 셋팅해준다. rootReducer 변수의 combineReducers의 인자로는 modules 폴더 안에 있는 state들을 key-value pair 형태로 들어가게 될 것이다.
import { createStore } from "redux";
import { combineReducers } from "redux";
const rootReducer = combineReducers({
key: value })
const store = createStore(rootReducer);
export default store;
3. index.js
store를 사용하기 위한 코드를 작성해준다. store를 상단에서 import해주고, Provider로 App 컴포넌트를 감싸준다.
...생략
import { Provider } from 'react-redux';
import store from './redux/config/configStore';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}> // <---여기
<App />
</Provider>
);
...생략
4. Modules 폴더 안에서 state 만들기
useState를 사용할 때 초깃값을 설정해줬던 것처럼 counter.js에서 카운터의 초깃값을 0으로 설정해준다.
초기 상탯값 아래에는 state에 변화를 일으키는 함수인 Reducer 를 만들어준다. 이 함수는 state와 action을 인자로 받는다.
const initialState = {
number: 0, // <---초깃값 설정
};
const counter = (state = initialState, action) => {
switch (action.type) { // <---reoducer 설정
default:
return state;
}
}
export default counter;
5. 만들어진 reducer를 Store에 모아주기
import { createStore } from "redux";
import { combineReducers } from "redux";
const rootReducer = combineReducers({
counter; counter }) // <---여기
const store = createStore(rootReducer);
export default store;
store에 접근하여 counter 값을 읽어오고 싶은 위치에서 Redux의 Hooks인 useSelector를 사용한다.
import React from "react";
import { useSelector } from "react-redux";
function App() {
const counter = useSelector((state) => {
return state.counter; // <--- 여기
});
console.log("counter -->", counter.number);
dispatch는 action(type, payload) 을 store에 던져주고, store는 받은 action의 타입에 따라 state를 변경한다.
1. reducer에 action type 설정하기
const initialState = {
number: 0,
};
const counter = (state = initialState, action) => {
switch (action.type) {
case "PLUS_ONE": // <---여기
return {
number: state.number + 1,
}
case "MINUS_ONE": // <---여기
return {
number: state.number - 1,
}
default:
return state;
}
}
export default counter;

2. dispatch로 action 던져주기
컴포넌트에 useDispatch를 import하고, dispatch를 가져온 다음, 함수가 실행되는 곳에 dispatch를 넣어준다. 이 때 dispatch()의 인자에는 위에서 미리 설정해 둔 action 객체를 넣어주면 된다.
import { useDispatch, useSelector } from "react-redux";
function App() {
const counter = useSelector((state) => {
return state.counter;
});
const dispatch = useDispatch(); // <--Dispatch 가져오기
console.log("counter -->", counter.number);
return <>
<div> 현재 카운트 : {counter.number} </div>
<button onClick={() => {
dispatch({
type: 'PLUS_ONE', // <--action 객체 넣어주기
})
}}>+</button>
<button onClick={() => {
dispatch({
type: 'MINUS_ONE', // <--action 객체 넣어주기
})
}}>-</button>
</>
}
export default App;