React๋ Redux๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ๋ถ๋ณ์ฑ์ด๋ผ๋ ๊ฐ๋
์ ๋ง์ด ๋ค์ด ๋ณผ ์ ์๋ค.
๋ถ๋ณ์ฑ์ ์ ์งํ๊ธฐ ์ํด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ ํนํ Redux-Toolkit์์๋ ๋ด์ฅ๋ ๋ฏธ๋ค์จ์ด๋ก Immer ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ค์ด๊ฐ ์๊ธฐ๋ ํ๋ค. ๋ถ๋ณ์ฑ์ด ๋ฌด์์ด๊ณ ๋ถ๋ณ์ฑ์ด ์ React์์ ์ค์ํ์ง ์์๋ณด๊ณ ๋ถ๋ณ์ฑ ์ ์ง๋ฅผ ์ฝ๊ฒ ํ๊ธฐ ์ํด ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฅ๋จ์ ์ ๋ํด์๋ ์์๋ณด์.
๋ถ๋ณ์ฑ์ ๋ง ๊ทธ๋๋ก ๋ณํ์ง ์๋ ๊ฐ์ด๋ ์ํ๋ฅผ ๋งํ๋ค. ์ฆ, ํ๋ฒ ์์ฑ๋ ๊ฐ์ ๋ณ๊ฒฝ๋ ์ ์๊ณ ๊ทธ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ถ๋ค๋ฉด ์๋ก์ด ๊ฐ์ ์์ฑํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
JavaScript์ ์์ ํ์ ์ ๋ถ๋ณ์ฑ์ ๊ฐ์ง๊ณ ์๋ค. ์์๊ฐ์ ์ข ๋ฅ๋ก๋ ๋ฌธ์(string), ์ซ์(number), bigint, ๋ถ๋ฆฐ(boolean), ์ฌ๋ณผ(symbol), null, undefined๊ฐ ์กด์ฌํ๋ค.
์์๋ฅผ ํตํด ์์ํ์ ์ ๋ถ๋ณ์ฑ์ ์ดํดํด๋ณด์.
let test = 'JavaScript'; // 1
test = 'React' // 2
์ ์์๋ ๋ณ์๋ฅผ ์ ์ธํ๊ณ ๊ทธ ๋ณ์์ ๋ฌธ์์ด์ ํ ๋นํ ํ, ๋ค๋ฅธ ๋ฌธ์์ด์ ํ ๋นํ๋ ๊ฒ์ ๋ํ๋ธ๋ค. ์์ ๊ฐ์ธ ๋ฌธ์์ด์ด ๋ณ๊ฒฝ๋๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง ๋ฌธ์์ด์ ๋ณ๊ฒฝ๋ ๊ฒ์ด ์๋๋ค.
ํ ์ค์ฉ ์ดํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
test ๋ณ์๊ฐ ์ ์ธ, 'JavaScript' ๋ฌธ์์ด ํ ๋น
์ด๋ ๋ฉ๋ชจ๋ฆฌ์๋ 'JavaScript'๋ผ๋ ๋ฌธ์์ด์ด ์์ฑ๋๊ณ test ๋ณ์๋ 'JavaScript'๊ฐ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
test ๋ณ์์ 'React' ๋ฌธ์์ด์ ๊ฐ์ผ๋ก ์ฌํ ๋น
์ด๋ test ๋ณ์๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ 'React'๊ฐ ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ์ ์์น๋ผ๋ ๊ฒ์ ์๋ฏธํ๋ค. ๊ทธ๋ ๋ค๋ฉด 'JavaScript' ๋ฌธ์์ด์ ์ด๋ป๊ฒ ๋ ๊ฑธ๊น? ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ๋ผ์ง ๊ฑธ๊น? ๋ต์ โ ์ด๋ค.
'JavaScript' ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ์ ๊ณ์ ์กด์ฌํ๊ณ 'React' ๋ฌธ์์ด์ด ์๋ก ์์ฑ๋๋ค. ์ฆ, ์์ ๋ณ์์ ๊ฐ์ด ์ฌํ ๋น ๋๋ค๋ ๊ฒ์ ๊ธฐ์กด ๋ฌธ์์ด์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์๋๋ผ ์๋กญ๊ฒ ๋ฉ๋ชจ๋ฆฌ์ ์์ฑ๋ ๊ฐ์ ๊ฐ๋ฆฌํค๋ ๊ฒ์ด๋ค.
์ฐธ์กฐ ํ์ ์ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค. ์ฐธ์กฐ ํ์ ์๋ ์์ ๊ฐ์ ์ข ๋ฅ๋ฅผ ์ ์ธํ ์ข ๋ฅ(๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ...)์ด๋ค.
๊ฐ์ฒด๋ก ์๋ฅผ ๋ค์ด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
const test = {
a: 'a value',
b: 'b value',
}; // 1
test.b = 'c value'; // 2
/*
console.log(test);
{ a: "a value", b: "c value" }
*/
test ๋ณ์ ์ ์ธ, ๊ฐ์ฒด ํ ๋น
์์๊ฐ๊ณผ ๋ฌ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์๋ ํด๋น ๊ฐ์ฒด๊ฐ ์ ์ฅ๋ ์ฃผ์๊ฐ์ด ์ ์ฅ๋๋ค. test๋ ์ด ์ฃผ์๊ฐ์ ๊ฐ๋ฆฌํจ๋ค.
test ๊ฐ์ฒด์ b ์์ฑ์ ๊ฐ์ ์ฌํ ๋น
์๋ณธ ๋ฐ์ดํฐ๊ฐ ์์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฐธ์กฐ ํ์
์์๋ ์ด๋ป๊ฒ ๋ถ๋ณ์ฑ์ ๊ฐ์ง ์ ์์๊น?
์์ ํ์
๊ณผ ๊ฐ์ด ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ํ ๋นํด ์ค์ผ ํ๋ค.
์ฆ, ์ ์์์ฒ๋ผ ์ผ๋ถ ์์ฑ์ ๋ค๋ฅด๊ฒ ํ ๋นํ๊ณ ์ถ์ง๋ง ๋ถ๋ณ์ฑ์ ์ ์งํด์ผ ํ๋ค๋ฉด
์๋์ ๊ฐ์ด ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์ฌํ ๋นํ์ฌ ์๋ณธ ๋ฐ์ดํฐ์ ์์ ์ด ์๋ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ์์ฑํด์ผ ํ๋ค.
let test = {
a: 'a value',
b: 'b value',
};
test = {
a: 'a value',
b: 'c value',
}
React๋ state๋ props๊ฐ ๊ฐฑ์ ๋ ๋, ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๋ค.
๊ทธ๋ ๋ค๋ฉด state๋ props์ ๋ณํ๋ฅผ ์ด๋ป๊ฒ ์์์ฐจ๋ฆด ์ ์์๊น?
์์ ๊ฐ์ ์ด์ state์ ์๋ก์ด state์ ์์ ๋น๊ต๋ฅผ ํตํด state๊ฐ ๋ณ๊ฒฝ๋๋ค๋ ๊ฒ์ ์๊ฒ ๋๋ค. ์์ ๋น๊ต๋ ์ฐธ์กฐ ํ์
์ธ ๋ฐฐ์ด์ด๋ ๊ฐ์ฒด์ ์์ฑ์ ํ๋ํ๋ ๋น๊ตํ๋ ๊ฒ์ด ์๋ ์ค์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ์์น์ ์ฃผ์ ์ฆ, ์ฐธ์กฐ ๊ฐ์ ๋น๊ตํ๋ค.
์ด๊ฒ ์ฐ๋ฆฌ๊ฐ React์์ ๋ถ๋ณ์ฑ์ ์ง์ผ์ผ ํ๋ ์ด์ ์ด๋ค.
๋ง์ฝ state๊ฐ ์๋์ ๊ฐ์ ๊ฐ์ฒด๋ผ๊ณ ๊ฐ์ ํด ๋ณด์.
const [state, setState] = useState({
a: { b: 'c' },
c: 'e',
});
setState({
...state,
c: 'f',
});
state๋ฅผ ๊ฐฑ์ ํ ๋, ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ setState์ ์ธ์๋ก ์ ๋ฌํ์ฌ state๋ฅผ ์ ๋ฐ์ดํธํ๋ค. ์ด์ state์ ์๋ก์ด state๋ ์๋ก ๋ค๋ฅธ ์ฐธ์กฐ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ React๋ state์ ๊ฐฑ์ ์ ์ถ์ ํ๊ณ ๋ฆฌ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ ์ ์๋ค.
์์ ํ์ ์ ์ ์ธํ ์ฐธ์กฐ ํ์ ์ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ .push์ ๊ฐ์ ๋ฉ์๋๋ก ์ง์ ๋ณ๊ฒฝํ๊ฒ ๋๋ฉด ๊ทธ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์๋ ๋ค๋ฅธ ๊ณณ์์ ์์ํ ์ ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๐ ์ถํ ์ค์ ์ด๋ค side effect ์ฌ๋ก๊ฐ ์๋ ์ง ์ถ๊ฐํ ์์ ์ ๋๋ค.
๋ถ๋ณ์ฑ์ ์งํค๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง ์กด์ฌํ๋ค.
1. map, filter, reduce ๋ฑ, ๊ธฐ์กด ๋ฐฐ์ด์ ๋ณ๊ฒฝํ์ง ์๊ณ ์๋ก์ด ๋ฐฐ์ด์ ๋ฐํํ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉ
2. spread operator(...)๋ก ๋ณต์ฌ๋ณธ์ ์ฌ์ฉ
3. Object.assign ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ๋ณต์ฌ
4. Object.freeze ๋ถ๋ณ ๊ฐ์ฒด ๋ง๋ค๊ธฐ
ํ์ง๋ง ์ด๋ฐ ์์
๋ค์ ์๋์ ํ์ง ์์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ํธํ๊ฒ ๋ถ๋ณ์ฑ์ ์ ์งํ ์ ์๋ค. ๋ถ๋ณ์ฑ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ๋ํ์ ์ธ ๋ ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์๋ณด๊ณ ์ฐจ์ด์ ์ ๋น๊ตํด ๋ณด์.
Immer๋ ๋ถ๋ณ state๋ฅผ ํธ๋ฆฌํ๊ฒ ์์ ํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. Immer๋ฅผ ์ฌ์ฉํ๋ฉด ์์์ ์์๋ดค๋ spread operator์ ๊ฐ์ ๋ถ๋ณ์ฑ์ ์งํค๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ง ์๊ณ ๋ณ๊ฒฝ์ฌํญ์ ์๋ณธ ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ธ draft ์์ ๊ฐ์ฒด์ ์ ์ฉํ ์ ์๋ค. Immer๋ ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฉ๋ draft ๊ฐ์ฒด๋ก ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
How Immer works
The basic idea is that with Immer you will apply all your changes to a temporary draft, which is a proxy of the currentState. Once all your mutations are completed, Immer will produce the nextState based on the mutations to the draft state. This means that you can interact with your data by simply modifying it while keeping all the benefits of immutable data.
์ถ์ฒ: Immer ๊ณต์ํํ์ด์ง
const initialState = {
page: {
title: "count",
count: 0,
}
};
// Immer ์ฌ์ฉ ์
export const reducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_COUNT':
return {
...state,
page: {
...state.page,
count: state.page.count + 1
},
};
default:
return state;
}
};
// Immer ์ฌ์ฉ ํ
import produce from 'immer'
export const reducer = produce(state = initialState, (draft) => {
switch (action.type) {
case 'ADD_COUNT':
draft.page.count = state.page.count + 1;
default:
return state;
}
});
Immutable.js๋ Immer์ ๊ฐ์ด ๋ถ๋ณ์ฑ์ ์ ์งํ๋ ๊ฒ์ ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
Immutable.js๋ List, Stack, Map, Set๊ณผ ๊ฐ์ ๋ง์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ๋ค. ์ด๋ฌํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋ฐ์ดํฐ์ ๊ฐฑ์ ์ด ์์ ๋, ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ ๊ฐ์ด ๋ฌ๋ผ์ง์ง ์์์ ๊ฒฝ์ฐ ๋์ผํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค. fromJS ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๊ผญ ๊ฐ์ฒด๋ฅผ Map, List ์ ๊ฐ์ ํจ์๋ฅผ ํธ์ถํ์ง ์๊ณ ๋ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์์ฑํด ์ค๋ค.
import { Map } from "immutable";
const initialState = Map({ // JavaScript์ ์ผ๋ฐ ๊ฐ์ฒด๊ฐ ์๋ Map ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ณ ์ปฌ๋ ์
์ ์์ฑํ๋ค.
page: Map({
title: "count",
count: 0,
})
});
export const reducer = (state = initialState, action) => {
const page = state.get('page');
switch (action.type) {
case 'ADD_COUNT':
return state.set('page', page.update((page) => page.set('count', page.get('count') + 1)));
default:
return state;
}
};
const result = [].withMutations(function (list) {
list.push(4).push(5).push(6);
}); // push๋ฅผ ์ฌ๋ฌ๋ฒ ํ์ง๋ง ์๋ก์ด ์ปฌ๋ ์
์ ํ๋๋ง ์์ฑ
๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ๊ฐ๊ฐ์ ์ฅ์ ๊ณผ ๋จ์ ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ ํ์ ๊ฐ๋ฐํ๋ ์ฌ๋์ด ํ์์ ๋ฐ๋ผ ๊ฒฐ์ ํ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ค๋ง Immutable-js ์ปฌ๋ ์
์ ํ์ต์ ๋ง์ ์๊ฐ์ ํฌ์ํ ์ ์๋ค๋ฉด ๊ฐ์ ๋ชฉ์ ์ ๊ฐ์ง๊ณ ์์ง๋ง JavaScript์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ์ฌ์ฉํ ์ ์๋ Immer๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์๋ชป๋ ๋ด์ฉ์ด๋ ์ถ๊ฐํ ์ ์๋ ๋ด์ฉ์ด ์๋ค๋ฉด ๋๊ธ ๋จ๊ฒจ์ฃผ์ธ์~
Immutability in React: Thereโs nothing wrong with mutating objects
๋ฆฌ์กํธ ๋ถ๋ณ์ฑ์ด๋ ๋ฌด์์ด๊ณ , ์ ์ง์ผ์ผ ํ ๊น?
spread operator๋ฅผ ์ฌ์ฉํ์ฌ setStateํ๊ธฐ
Immer and Immutable.js: How do they compare?
Immutable collections for JavaScript
Immutable js ๊ฐ๋จ์ ๋ฆฌ
์๋ ์ค์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ์์น์ ์ฃผ์ ์ฆ, ์ฐธ์กฐ ๊ฐ์ ๋น๊ตํ๋ค. Area Code