코드의 복잡성이 높아짐 -> 코드의 복잡성을 낮추자
애플리케이션의 복잡성을 낮춘다.
Single Source of Truth (하나의 상태)
state = {}에 애플리케이션에 필요한 모든 데이터를 넣는다.
디스패쳐, 리듀서를 통해서만 데이터를 수정할 수 있다.
getState를 통해서만 데이터를 가져갈 수 있다.
// state값을 직접 변경해주는 reducer
function reducer(state, action) {
if(state === undefined) {
return {
color: 'red'
}
}
}
// store 생성: reducer를 인자로 받음
const store = Redux.createStore(reducer);
// state를 가져올때는 getState()함수를 통해서 가져와야함
const state = store.getState();
// state값을 직접 변경해주는 reducer
function reducer(state, action) {
let newState;
if(state === undefined) {
return {
color: 'red'
}
}
else if(action.type === 'CHANGE_COLOR') {
newState = {...state, color: action.color}
}
return newState;
}
// store 생성: reducer를 인자로 받음
const store = Redux.createStore(reducer);
// dispatch : action을 발생시킴
store.dispatch(
// action
{type:'CHANGE_COLOR', color:'red'}
);
function func() {
console.log('function');
}
// state가 바뀔 때 func 실행
store.subscribe(func);
<html>
<head>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.1.0/redux.js"
integrity="sha512-tqb5l5obiKEPVwTQ5J8QJ1qYaLt+uoXe1tbMwQWl6gFCTJ5OMgulwIb3l2Lu7uBqdlzRf5yBOAuLL4+GkqbPPw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<style>
.box {
border: 5px solid black;
height: 100px;
}
</style>
<div class="box red">
<button onclick="changeColor('red')">red</button>
</div>
<div class="box blue">
<button onclick="changeColor('blue')">blue</button>
</div>
<div class="box green">
<button onclick="changeColor('green')">green</button>
</div>
<script>
function reducer(state, action) {
let newState;
if (!state) {
newState = { color: "yellow" };
} else if (action.type === "CHANGE_COLOR") {
newState = { ...state, color: action.color };
}
return newState;
}
const store = Redux.createStore(reducer);
function changeColor(color) {
store.dispatch({ type: "CHANGE_COLOR", color: color });
}
function render() {
document.querySelector(".red").style.backgroundColor =
store.getState().color;
document.querySelector(".blue").style.backgroundColor =
store.getState().color;
document.querySelector(".green").style.backgroundColor =
store.getState().color;
}
render();
store.subscribe(render);
</script>
</body>
</html>
<html>
<head>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.1.0/redux.js"
integrity="sha512-tqb5l5obiKEPVwTQ5J8QJ1qYaLt+uoXe1tbMwQWl6gFCTJ5OMgulwIb3l2Lu7uBqdlzRf5yBOAuLL4+GkqbPPw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="createMode"></div>
<div id="content"></div>
<script>
function reducer(state, action) {
let newState;
if (!state) {
newState = {
contents: [
{ id: 1, title: "HTML", desc: "HTML is ..." },
{ id: 2, title: "CSS", desc: "CSS is ..." },
],
selectedId: 1,
mode: "read",
};
} else if (action.type === "SELECT") {
newState = { ...state, selectedId: action.id };
} else if (action.type === "ADD_ARTICLE") {
let newId = 0;
for (const content of state.contents) {
if (newId < content.id) {
newId = content.id;
}
}
newId++;
newState = { ...state };
newState.contents.push({
id: newId,
title: action.title,
desc: action.desc,
});
newState.selectedId = newId;
} else if (action.type === "TOGGLE_MODE") {
newState = { ...state };
const newMode = newState.mode === "read" ? "create" : "read";
newState.mode = newMode;
} else if (action.type === "DELETE_ARTICLE") {
newState = { ...state };
const newContents = newState.contents.filter(
(content) => content.id !== state.selectedId
);
newState.contents = newContents;
newState.selectedId = 0;
}
console.log(action.type, action, state, newState);
return newState;
}
const store = Redux.createStore(reducer);
function subject() {
document.querySelector("#subject").innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB
</header>
`;
}
function TOC() {
const contents = store.getState().contents;
let lis = "";
contents.forEach((content) => {
lis += `<li><a href='#' onclick='select(${content.id})'>${content.title}</a></li>`;
});
document.querySelector("#toc").innerHTML = `
<nav>
<ol>
${lis}
</ol>
</nav>
`;
}
function control() {
const mode = store.getState().mode;
document.querySelector("#control").innerHTML = `
<div>
<button>${
mode === "read" ? "create" : "read"
}</button>
<button>delete</button>
</div>
`;
}
function createMode() {
if (store.getState().mode !== "create") {
document.querySelector("#createMode").innerHTML = `
`;
} else {
document.querySelector("#createMode").innerHTML = `
<input id='title' placeholder='title' /> <br />
<textarea id='desc' placeholder='description' ></textarea> <br />
<button>등록</button>
`;
}
}
function article() {
const selectedId = store.getState().selectedId;
if (selectedId === 0) {
document.querySelector("#content").innerHTML = `
<article>
</article>
`;
return;
}
const contents = store.getState().contents;
const content = contents.find((content) => content.id === selectedId);
document.querySelector("#content").innerHTML = `
<article>
<h2>${content.title}</h2>
${content.desc}
</article>
`;
}
function toggleMode() {
store.dispatch({ type: "TOGGLE_MODE" });
}
function select(id) {
store.dispatch({ type: "SELECT", id: id });
}
function addArticle() {
const $title = document.querySelector("#title");
const $desc = document.querySelector("#desc");
const titleValue = $title.value;
const descValue = $desc.value;
if (!titleValue || !descValue) return;
store.dispatch({
type: "ADD_ARTICLE",
title: titleValue,
desc: descValue,
});
$title.value = "";
$desc.value = "";
}
function deleteArticle() {
store.dispatch({ type: "DELETE_ARTICLE" });
}
subject();
TOC();
control();
createMode();
article();
store.subscribe(TOC);
store.subscribe(article);
store.subscribe(createMode);
store.subscribe(control);
</script>
</body>
</html>