반응형
Redux로 간단한 웹사이트 구현하기
Redux만으로도 간단한 웹 CRUD을 구현할 수 있다.
1. 기본적인 HTML 뼈대 구현
<!DOCTYPE html>
<html>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="content"></div>
<script>
function subject(){
document.querySelector('#subject').innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB!
</header>
`
}
function TOC(){
document.querySelector('#toc').innerHTML = `
<nav>
<ol>
<li><a href="1.html">HTML</a></li>
<li><a href="2.html">CSS</a></li>
</ol>
</nav>
`;
}
function control(){
document.querySelector('#control').innerHTML = `
<ul>
<li><a href="/create">create</a></li>
<li><input type="button" value="delete"></li>
</ul>
`;
}
function article(){
document.querySelector('#content').innerHTML = `
<article>
<h2>HTML</h2>
HTML is ...
</article>
`
}
<!--모듈화로 부품처럼 함수로 처리하여 분리해놓고 아래에 함수를 호출하는 것을 모아놓았다.-->
subject();
TOC();
control();
article();
</script>
</body>
</html>
2. store 생성과 state 사용하기
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
</head>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="content"></div>
<script>
function subject(){
document.querySelector('#subject').innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB!
</header>
`
}
function TOC(){
//contents의 배열 값이 들어있는 store을 getState 메소드를 이용하여 state을 변수 선언하고 삽입
var state = store.getState();
var i = 0;
var liTags = '';
while(i<state.contents.length){
//결국 가져온 contents의 배열 값을 while문을 통해 목록 링크 리스트 생성함.
liTags = liTags + `
<li>
<a href="${state.contents[i].id}">${state.contents[i].title}</a>
</li>`;
i = i + 1;
}
document.querySelector('#toc').innerHTML = `
<nav>
<ol>${liTags}</ol>
</nav>
`;
}
function control(){
document.querySelector('#control').innerHTML = `
<ul>
<li><a href="/create">create</a></li>
<li><input type="button" value="delete"></li>
</ul>
`;
}
function article(){
document.querySelector('#content').innerHTML = `
<article>
<h2>HTML</h2>
HTML is ...
</article>
`
}
function reducer(state, action){
if(state === undefined){ //reducer 처음 초기값은 undefined이므로 if문으로 조건 삽입
return {
//contents 배열을 설정
contents:[
{id:1,title:'HTML',desc:'HTML is ..'},
{id:2,title:'CSS', desc:'CSS is ..'}
]
}
}
}
//reducer와 연결하여 contents의 배열 값을 store 변수로 선언하여 삽입.
var store = Redux.createStore(reducer);
subject();
TOC();
control();
article();
</script>
</body>
</html>
3. action을 dispatch를 통해서 전달하기
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
</head>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="content"></div>
<script>
function subject(){
document.querySelector('#subject').innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB!
</header>
`
}
function TOC(){
var state = store.getState();
var i = 0;
var liTags = '';
while(i<state.contents.length){
liTags = liTags + `
<li>
// 클릭 이벤트를 주었는데 event.preventDefault();로 의도치 않은 링크를 타지 않게 하였으고
// store.dispatch(action);을 통해 store에 타입과 id값을 담은 action 변수를 담아주었다.
<a onclick="
event.preventDefault();
var action = {type:'SELECT', id:${state.contents[i].id}}
store.dispatch(action);
" href="${state.contents[i].id}">
${state.contents[i].title}
</a>
</li>`;
i = i + 1;
}
document.querySelector('#toc').innerHTML = `
<nav>
<ol>${liTags}</ ol>
</nav>
`;
}
function control(){
document.querySelector('#control').innerHTML = `
<ul>
<li><a href="/create">create</a></li>
<li><input type="button" value="delete"></li>
</ul>
`;
}
function article(){
document.querySelector('#content').innerHTML = `
<article>
<h2>HTML</h2>
HTML is ...
</article>
`
}
function reducer(state, action){
if(state === undefined){
return {
//id 식별 추가
selcted_id:null,
contents:[
{id:1,title:'HTML',desc:'HTML is ..'},
{id:2,title:'CSS', desc:'CSS is ..'}
]
}
}
var newState;
// action으로 들어온 타입 값이 'SELECT'이면 if문 발동
//state에 id 식별 값 복제해주었다. 그리고 newState에 변수로 담았다.
if(action.type === 'SELECT'){
newState = Object.assign({}, state, {selcted_id:action.id});
}
return newState;
}
var store = Redux.createStore(reducer);
subject();
TOC();
control();
article();
</script>
</body>
</html>
4. subscribe를 통해서 자동 갱신 되도록 처리
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
</head>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="content"></div>
<script>
function subject(){
document.querySelector('#subject').innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB!
</header>
`
}
function TOC(){
var state = store.getState();
var i = 0;
var liTags = '';
while(i<state.contents.length){
liTags = liTags + `
<li>
<a onclick="
event.preventDefault();
var action = {type:'SELECT', id:${state.contents[i].id}}
store.dispatch(action);
" href="${state.contents[i].id}">
${state.contents[i].title}
</a>
</li>`;
i = i + 1;
}
document.querySelector('#toc').innerHTML = `
<nav>
<ol>${liTags}</ ol>
</nav>
`;
}
function control(){
document.querySelector('#control').innerHTML = `
<ul>
<li><a href="/create">create</a></li>
<li><input type="button" value="delete"></li>
</ul>
`;
}
function article(){
//store에서 .getState() 메소드를 이용하여 reducer 함수의 state 값들을 가져와서
//while문을 통해 state 값들을 id 식별자에 따라 웹 페이지에 목록의 내용을 표시하도록 하였다.
var state = store.getState();
var i = 0;
var aTitle, aDesc;
while(i < state.contents.length){
//state 배열 id값 중 클릭 이벤트로 선택된 id 식별값이 같은 배열 값만 통과하도록 하였다.
if(state.contents[i].id === state.selcted_id) {
aTitle = state.contents[i].title;
aDesc = state.contents[i].desc;
break;
}
i = i + 1;
}
document.querySelector('#content').innerHTML = `
<article>
<h2>${aTitle}</h2> //id값이 같아 if문을 통과하여 담긴 변수를 html에 표시하도록 함.
${aDesc} //
</article>
`
}
function reducer(state, action){
if(state === undefined){
return {
selcted_id:2,
contents:[
{id:1,title:'HTML',desc:'HTML is ..'},
{id:2,title:'CSS', desc:'CSS is ..'}
]
}
}
var newState;
if(action.type === 'SELECT'){
newState = Object.assign({}, state, {selcted_id:action.id});
}
console.log(action, state, newState);
return newState;
}
var store = Redux.createStore(reducer);
store.subscribe(article);
subject();
TOC();
control();
article();
</script>
</body>
</html>
5. 글 생성 및 삭제 기능
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
</head>
<body>
<div id="subject"></div>
<div id="toc"></div>
<div id="control"></div>
<div id="content"></div>
<script>
function subject(){
document.querySelector('#subject').innerHTML = `
<header>
<h1>WEB</h1>
Hello, WEB!
</header>
`
}
function TOC(){
var state = store.getState();
var i = 0;
var liTags = '';
while(i<state.contents.length){
liTags = liTags + `
<li>
<a onclick="
event.preventDefault();
var action = {type:'SELECT', id:${state.contents[i].id}}
store.dispatch(action);
" href="${state.contents[i].id}">
${state.contents[i].title}
</a>
</li>`;
i = i + 1;
}
document.querySelector('#toc').innerHTML = `
<nav>
<ol>${liTags}</ ol>
</nav>
`;
}
function control(){
document.querySelector('#control').innerHTML = `
<ul>
//create 버튼을 클릭할때 이벤트를 설정해주었고
//dispatch을 통해 store에 클릭 이벤트 발생 시 변화될 type과 mode을 넣어주었다.
<li><a onclick="
event.preventDefault();
store.dispatch({
type:'CHANGE_MODE',
mode:'create'
})
" href="/create">create</a></li>
//마찬가지로 delete 버튼에도 dispatch 메소드를 이용하여 클릭 발생시 타입을 store에 넣어줌.
<li><input onclick="
store.dispatch({
type:'DELETE'
});
" type="button" value="delete"></li>
</ul>
`;
}
function article(){
var state = store.getState();
if(state.mode === 'create'){
document.querySelector('#content').innerHTML = `
<article>
//create 버튼을 누르면 글을 생성하기 위한 구성 데이터를 보낼 폼이 등장하도록 하였다.
<form onsubmit="
event.preventDefault();
var _title = this.title.value;
var _desc = this.desc.value;
store.dispatch({
//폼에서 받은 value값을 담은 변수 title, desc을 dispatch을 통해 store에 담아줌.
type:'CREATE',
title:_title,
desc:_desc
})
">
<p>
<input type="text" name="title" placeholder="title">
</p>
<p>
<textarea name="desc" placeholder="description"></textarea>
</p>
<p>
<input type="submit">
</p>
</form>
</article>
`
} else if(state.mode === 'read'){
var i = 0;
var aTitle, aDesc;
while(i < state.contents.length){
if(state.contents[i].id === state.selcted_id) {
aTitle = state.contents[i].title;
aDesc = state.contents[i].desc;
break;
}
i = i + 1;
}
document.querySelector('#content').innerHTML = `
<article>
<h2>${aTitle}</h2>
${aDesc}
</article>
`
//delete 후 이동할 초기 화면으로 welcome 모드를 설정해 주었다.
} else if(state.mode === 'welcome'){
document.querySelector('#content').innerHTML = `
<article>
<h2>Welcome</h2>
Hello, Redux!!!
</article>
`
}
}
function reducer(state, action){
if(state === undefined){
return {
max_id:2, //create가 새로운 id 값을 추가하기 전에 이렇게 최대 id값을 표시해준다.
mode:'welcome', //
selcted_id:2,
contents:[
{id:1,title:'HTML',desc:'HTML is ..'},
{id:2,title:'CSS', desc:'CSS is ..'}
]
}
}
var newState;
if(action.type === 'SELECT'){
newState = Object.assign(
{},
state,
{selcted_id:action.id, mode:'read'});
} else if(action.type === 'CREATE'){
//여기서 글이 생성된다.
//id 값 새로 생성하여 생기는 id 값이 늘어나게하는 코드
var newMaxId = state.max_id + 1;
//concat 메소드를 통해 contents와 같은 배열을 복제하여 newContents에 담아줌.
var newContents = state.contents.concat();
//그리고 push 메소드를 통해 새로운 글을 생성하는데 필요한 글을 구성하는 근복적 코드들 삽입
newContents.push({id:newMaxId, title:action.title, desc:action.desc});
// assign 메소드를 통해 max_id, contents, mode을 생성한 데이터를 통해 업데이트 해줌.
newState = Object.assign({}, state, {
max_id:newMaxId,
contents:newContents,
mode:'read'
})
//action의 타입이 delete인 경우 아래 코드 발생
} else if(action.type === 'DELETE'){
//마찬가지로 while문을 이요하여 state의 contents 배열 값을 돌려
//클릭 이벤트로 인하여 보내진 특정 id 식별자와 동일한 배열 값을 찾아내어 이 동일한 배열
//값만을 newContets에 담지 않았다. 이렇게 담아지지 못한 배열 값은 삭제가 된 것이다.
var newContents = [];
var i = 0;
while(i < state.contents.length){
if(state.selcted_id !== state.contents[i].id){
newContents.push(
state.contents[i]
);
}
i = i + 1;
}
//새로 담아진 newCotents 값을 assign 메소드를 통해 newState 변수에 담아주었고
//mode 또한 초기화면으로 돌아가기 위해 welcome 모드로 변환해주었다.
newState = Object.assign({},state, {
contents:newContents,
mode:'welcome'
})
//타입이 CHANGE_MODE 일때 newState에 assign을 통해 action.mode로 모드 변경해주는 것을 담음.
} else if(action.type === 'CHANGE_MODE'){
newState = Object.assign({}, state, {
mode:action.mode
});
}
return newState;
}
var store = Redux.createStore(reducer);
store.subscribe(article);//state 값이 바꼈을때 subscribe을 통해 바로 웹에 반응하도록 했다.
store.subscribe(TOC); //state 값이 바꼈을때 subscribe을 통해 바로 웹에 반응하도록 했다.
subject();
TOC();
control();
article();
</script>
</body>
</html>
위의 이미지에서 볼수 있듯이 간단한 CRUD을 Redux를 통해 구현할 수 있게되었다. 삭제, 생성이 되는 것을 테스트로 확인 할 수 있었다.
반응형
'프로그래밍 개발 > Redux' 카테고리의 다른 글
Redux - Redux 구현하기 (0) | 2021.01.23 |
---|---|
Redux - Redux란? (0) | 2021.01.23 |
댓글