๐ Flux ํบ์๋ณด๊ธฐ!
Flux๋ Facebook์ด ๋ง๋ ์ ํ๋ฆฌ์ผ์ด์ ์ํคํ ์ฒ๋ก, ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์ค์ฌ์ผ๋ก ์ค๊ณ๋์์ต๋๋ค. React์ ํจ๊ป ์ฌ์ฉํ๋ฉด ์์ฃผ ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ๋์ฃ . ์ค๋์ Flux์ ๊ธฐ๋ณธ ๊ฐ๋ , ๊ตฌ์ฑ ์์, ๋์ ๋ฐฉ์, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์ด๋ป๊ฒ ํ์ฉ๋๋์ง์ ๋ํด ๊น์ด ์๋ ์ด์ผ๊ธฐ๋ฅผ ๋๋ ๋ณผ๊ฒ์. ๐ก
๐ Flux๋ ์ ๋ฑ์ฅํ์๊น?
React๋ UI ๋ ๋๋ง์ ๊ฐ๋ ฅํ์ง๋ง, ์ํ ๊ด๋ฆฌ์ ๋ํ ๋ช ํํ ๊ท์น์ ์์ด์. ํนํ, ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ฑฐ๋ ๊ณต์ ํด์ผ ํ ๋, ๋ถ๋ชจ-์์ ๊ฐ์ ์ํ ์ ๋ฌ์ด ๋ณต์กํด์ง๊ฑฐ๋, ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฌ ๊ณณ์์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ํฉ์์ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๋๋ค.
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฑ์ฅํ ๊ฒ์ด Flux์์. โ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆโ์ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ๋ ์์ธก ๊ฐ๋ฅํ๊ณ , ๋๋ฒ๊น ํ๊ธฐ ์ฌ์ด ํํ๋ก ๊ด๋ฆฌํ ์ ์๊ฒ ํ์ฃ .
๐ Flux์ ํต์ฌ ์๋ฆฌ
Flux๋ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ณ ์์ต๋๋ค. ๊ฐ๋จํ ๋งํด, ๋ฐ์ดํฐ๊ฐ ํ ๋ฐฉํฅ์ผ๋ก๋ง ํ๋ฅด๋๋ก ๊ฐ์ ํ์ฌ ๋ฐ์ดํฐ ์ํ๋ฅผ ๋ช ํํ ๊ด๋ฆฌํฉ๋๋ค.
๐ Flux์ 4๊ฐ์ง ๊ตฌ์ฑ ์์
1. Action (ํ๋)
- ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ๋ฌ์ฌํ ๊ฐ์ฒด
- ์ด๋ค ์ข ๋ฅ์ ๋์์ด ํ์ํ์ง์ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ํฌํจ
- ์: ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ๊ฑฐ๋, ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์์ฒญ
const addTodoAction = {
type: "ADD_TODO",
payload: { text: "Learn Flux" },
};
2. Dispatcher (๋์คํจ์ฒ)
- ๋ชจ๋ Action์ ์ค์์์ ๊ด๋ฆฌํ๋ฉฐ, ์ด๋ฅผ Store์ ์ ๋ฌ
- ๋จ์ผ Dispatcher๊ฐ ๋ชจ๋ Action์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ ํ๋ฆ์ด ์์ธก ๊ฐ๋ฅํด์ง๋๋ค.
dispatcher.dispatch({
type: "ADD_TODO",
payload: { text: "Learn Flux" },
});
3. Store (์ ์ฅ์)
- ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ์ฅํ๋ ๊ณณ
- Action์ด Dispatcher๋ฅผ ํตํด ์ ๋ฌ๋๋ฉด Store๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ
- React ์ปดํฌ๋ํธ๋ Store๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ๋ (subscribe)
const todoStore = {
todos: [],
addChangeListener(callback) {
this.onChange = callback;
},
dispatchHandler(action) {
if (action.type === "ADD_TODO") {
this.todos.push(action.payload.text);
this.onChange();
}
},
};
dispatcher.register(todoStore.dispatchHandler.bind(todoStore));
4. View (๋ทฐ)
- React ์ปดํฌ๋ํธ๊ฐ View์ ์ญํ
- Store์์ ์ํ๋ฅผ ๊ฐ์ ธ์ UI๋ฅผ ๋ ๋๋งํ๊ณ , ์ฌ์ฉ์์ ์ ๋ ฅ์ Action์ผ๋ก ๋ณํ
function TodoApp({ todos }) {
return (
<div>
{todos.map((todo, index) => (
<p key={index}>{todo}</p>
))}
<button onClick={() => addTodoAction("Learn Flux")}>
Add Todo
</button>
</div>
);
}
๐ Flux์ ๋ฐ์ดํฐ ํ๋ฆ
- ์ฌ์ฉ์ ์
๋ ฅ โ Action ์์ฑ
- ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ๊ฑฐ๋ ํผ์ ์ ์ถํ๋ฉด Action ๊ฐ์ฒด๊ฐ ์์ฑ๋ฉ๋๋ค.
- Dispatcher โ Store ์
๋ฐ์ดํธ
- Dispatcher๊ฐ Action์ ๋ฐ์์ Store๋ก ์ ๋ฌํฉ๋๋ค.
- Store๋ Action์ ๋ฐ๋ผ ์ํ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
- Store โ View ์
๋ฐ์ดํธ
- ์ํ๊ฐ ์ ๋ฐ์ดํธ๋๋ฉด Store๋ ๋ณ๊ฒฝ ์ฌํญ์ View์ ์๋ฆฝ๋๋ค.
- React๋ ์ํ ๋ณํ์ ๋ฐ๋ผ UI๋ฅผ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
- React โ ์ฌ์ฉ์ ์
๋ ฅ
- React๋ ์ฌ์ฉ์๋ก๋ถํฐ ์๋ก์ด ์ ๋ ฅ์ ๋ฐ์ ๋ค์ Action์ ์์ฑํฉ๋๋ค.
๐ ์ค๋ฌด์์ Flux ์ฌ์ฉํ๊ธฐ
1. ์ํ ๊ด๋ฆฌ์ ๋ณต์ก์ฑ ์ค์ด๊ธฐ
Flux๋ ๋ฐ์ดํฐ ํ๋ฆ์ ๋จ๋ฐฉํฅ์ผ๋ก ์ ์งํ๋ฏ๋ก, ์ํ ๋ณํ๊ฐ ์์ธก ๊ฐ๋ฅํ๊ณ ๋๋ฒ๊น ์ด ์ฌ์์ง๋๋ค.
2. ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์
์ปดํฌ๋ํธ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ์ด ๋ณต์กํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํนํ ์ ์ฉํฉ๋๋ค.
3. Redux์์ ๊ด๊ณ
Redux๋ Flux ์ํคํ ์ฒ์์ ์๊ฐ์ ๋ฐ์ ๋ง๋ค์ด์ง ์ํ ๊ด๋ฆฌ ๋๊ตฌ์ ๋๋ค. Flux์ ๊ตฌํ์ ๋จ์ํํ๊ณ , ๋จ์ผ Store๋ฅผ ์ฌ์ฉํ์ฌ ๊ด๋ฆฌ ํจ์จ์ฑ์ ๋์์ต๋๋ค.
โ ๏ธ Flux ์ฌ์ฉ ์ ์ฃผ์ํ ์
- Dispatcher๋ ๋จ์ผํด์ผ ํ๋ค
- ์ฌ๋ฌ Dispatcher๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐ์ดํฐ ํ๋ฆ์ ํผ๋์ค๋ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ํญ์ ํ๋์ Dispatcher๋ก ์ค์์์ Action์ ๊ด๋ฆฌํ์ธ์.
- Store๋ ์ํ๋ง ๊ด๋ฆฌํด์ผ ํ๋ค
- Store๋ UI๋ฅผ ๋ ๋๋งํ๊ฑฐ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํด์๋ ์ ๋ฉ๋๋ค. ์ค์ง ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐ ์ง์คํ์ธ์.
- Action์ ์์ํด์ผ ํ๋ค
- Action์ ์ํ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ , ๋จ์ง ์ํ ๋ณํ์ ์๋๋ฅผ ๋ํ๋ด๋ ๊ฐ์ฒด์ฌ์ผ ํฉ๋๋ค.
๐ฏ ๊ฐ๋จํ Todo ์์
// Dispatcher ์์ฑ
const dispatcher = {
callbacks: [],
register(callback) {
this.callbacks.push(callback);
},
dispatch(action) {
this.callbacks.forEach((callback) => callback(action));
},
};
// Store ์์ฑ
const todoStore = {
todos: [],
onChange: null,
dispatchHandler(action) {
if (action.type === "ADD_TODO") {
this.todos.push(action.payload.text);
this.onChange();
}
},
};
dispatcher.register(todoStore.dispatchHandler.bind(todoStore));
// View ์
๋ฐ์ดํธ
todoStore.onChange = function () {
console.log("Todos:", todoStore.todos);
};
// Action ์์ฑ ๋ฐ ๋์คํจ์น
dispatcher.dispatch({
type: "ADD_TODO",
payload: { text: "Learn Flux" },
});
๐ Flux๊ฐ ์ ์ค์ํ๊ฐ?
- Flux๋ React์ ์ฒ ํ์ธ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์ฒด๊ณ์ ์ผ๋ก ๊ตฌํํ ์ ์๊ฒ ๋์ต๋๋ค.
- ์ํ ๊ด๋ฆฌ๊ฐ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ ํ๋ฆ์ ์์ธก ๊ฐ๋ฅํ๊ณ ์์ ์ ์ผ๋ก ๋ง๋ค์ด์ค๋๋ค.
- Redux, MobX ๋ฑ ๋ง์ ์ํ ๊ด๋ฆฌ ๋๊ตฌ๊ฐ Flux์ ๊ฐ๋ ์ ๋ฐํ์ผ๋ก ํ์ํ์ผ๋ฉฐ, ์ด๋ฅผ ์ดํดํ๋ฉด ์ํ ๊ด๋ฆฌ ๋๊ตฌ๋ฅผ ๋ ์ ํ์ฉํ ์ ์์ต๋๋ค.
๋ง๋ฌด๋ฆฌํ๋ฉฐ ๐
Flux๋ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ํตํด ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ๋ ฅํ ์ํคํ ์ฒ์ ๋๋ค. React์์ ์กฐํฉ์ ํ๋ ์น ๊ฐ๋ฐ์์ ํ์์ ์ด๊ณ , ์ด๋ฅผ ์ ๋๋ก ์ดํดํ๋ฉด ๋ ๋์ ๊ฐ๋ฐ์๊ฐ ๋ ์ ์์ด์.
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท