1. store 생성
우리가 redux를 사용하기 위해서 제일 첫 번째를 store를 만들어야 하는 동시에 reducer를 생성해야 했다.
그리고 <head> 부분에 redux를 로딩해주었다.
main.html
<!DOCTYPE html>
<html>
<head>
<!--redux를 웹페이지에 로딩-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.0/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(){
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>
`
}
function reducer(state, action){ //이전의 상태 값과 호출된 이후의 action 값을 받는다.
if(state === undefined){ //초기값 셋팅
return{
contents:[
{id:1, title:'HTML', desc:'HTML is ...'},
{id:2, titme:'CSS', desc: 'CSS is ...'}
]
}
}
return //새로운 상태값 반환
}
var store = Redux.createStore(reducer); //store생성
subject();
TOC();
control();
article();
</script>
</body>
</html>
결과화면
store.getState()를 통해 초기값도 잘 설정되었는지 확인할 수 있다.
2. state 사용하기
코드에서 TOC의 함수의 내부를 보면 글목록이 있는데 글목록을 store에 있는 정보를 바탕으로 가져올 것이다.
main.html
<!DOCTYPE html>
<html>
<head>
<!--redux를 웹페이지에 로딩-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.0/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 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){ //이전의 상태 값과 호출된 이후의 action 값을 받는다.
if(state === undefined){ //초기값 셋팅
return{
contents:[
{id:1, title:'HTML', desc:'HTML is ...'},
{id:2, title:'CSS', desc: 'CSS is ...'}
]
}
}
return //새로운 상태값 반환
}
var store = Redux.createStore(reducer); //store생성
subject();
TOC();
control();
article();
</script>
</body>
</html>
이런 식으로 각각의 구성요소가 store에서 state를 가져온 다음, state값을 기반으로 html코드를 생성해주면 그 state에 따라 만들어지는 웹 페이지를 생성할 수 있다.
강의 영상 - https://youtu.be/NK7p71gDVTU
3. action을 dispatch를 통해 전달
이제 store의 state값을 변경하려고 한다.
이때, 그러기 위해서는 action을 발생시키고, 그 action이 dispatch를 통해서 reducer를 실행시키면 reducer가 state의 새로운 값을 내보내준다. 그리고 state의 값이 바뀌면 subscribe하고 있는 함수들을 호출해 주는 것을 통해 UI가 업데이트 된다는 것을 상기하고 코드를 작성해보자.
글 목록을 클릭했을 때 action이 만들어지도록 할 것이다.
main.html
<!DOCTYPE html>
<html>
<head>
<!--redux를 웹페이지에 로딩-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.0/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(); <!--event가 발생했을 때 event를 발생시킨 태그의 기본 동작을 방지-->
var action = {type: 'SELECT', id:${state.contents[i].id}} //type은 action에서 필수적
store.dispatch(action); //dispatch로 action정보가 넘어감. 그리고 reducer 호출됨
"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){ //이전의 상태 값과 호출된 이후의 action 값을 받는다.
if(state === undefined){ //초기값 셋팅
return{
selected_id:null,
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, {selected_id:action.id});
//state의 속성값이 빈객체에 복제되고, 그것이 newState가 된다.
//즉, newState는 기존의 값인 state에 selected_id값이 덮어쓰기 된 값이 된다.
}
console.log(action, state, newState);
return newState;
}
var store = Redux.createStore(reducer); //store생성
subject();
TOC();
control();
article();
</script>
</body>
</html>
결과화면
첫 번째는 HTML을 클릭했을 때이고, 두 번째가 CSS를 클릭했을 때이다.
첫 번째 클릭했을 때 값을 보면 selected_id값이 1번이고, array 2개 있다는 것을 확인할 수 있다.
두 번째 클릭했을 때 값을 보면 노란색은 action, 초록색은 이전의 state, 하늘색을 새로 만들어진 state를 나타낸다.
그리고 store.getstate()를 통해 우리가 선택한 selected_id값이 잘 셋팅된 것을 확인할 수 있다.
강의 영상 - https://youtu.be/ldxFOG4GfLk
4. subscribe를 통해 자동 갱신 처리
이제 selected_id라는 state값에 따라 본문 영역이 그에 맞는 내용을 보여주도록 할 것이다.
그럴려면 article이 state값에 맞게 바뀌어야 한다.
그리고 state값이 바뀌었을 때 자동으로 article 함수가 호출되도록 해야 한다.
main.html
<!DOCTYPE html>
<html>
<head>
<!--redux를 웹페이지에 로딩-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.0/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(); <!--event가 발생했을 때 event를 발생시킨 태그의 기본 동작을 방지-->
var action = {type: 'SELECT', id:${state.contents[i].id}} //type은 action에서 필수적
store.dispatch(action); //dispatch로 action정보가 넘어감. 그리고 reducer 호출됨
"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(){
var state = store.getState();
var i = 0;
var aTitle, aDesc;
while(i < state.contents.length){
if(state.contents[i].id === state.selected_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>
`
}
function reducer(state, action){ //이전의 상태 값과 호출된 이후의 action 값을 받는다.
if(state === undefined){ //초기값 셋팅
return{
selected_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, {selected_id:action.id});
//state의 속성값이 빈객체에 복제되고, 그것이 newState가 된다.
//즉, newState는 기존의 값인 state에 selected_id값이 덮어쓰기 된 값이 된다.
}
console.log(action, state, newState);
return newState;
}
var store = Redux.createStore(reducer); //store생성
store.subscribe(article);//subscribe는 값이 바뀌면 함수를 자동으로 호출함
subject();
TOC();
control();
article();
</script>
</body>
</html>
결과화면
HTML을 클릭했을 때와 CSS를 클릭했을 때 본문의 내용이 잘 바뀌는 것을 볼 수 있다.
그렇다면 배웠던 것을 복습삼아 왜 바뀌는지 생각해보자.
우리는 action을 통해 dispatch에 값을 전달하고 reducer가 state값을 갱신해 dispatch가 subscribe하고 있는 함수들을 호출해주기 때문에 그에 따라 render가 동작해 새로운 state값을 참조하여 UI를 새로 그리기 때문이다.
강의영상 - https://youtu.be/zMTqWoe25aU
'🌐 Web > Redux' 카테고리의 다른 글
09. 웹페이지 만들기(3) (0) | 2022.09.15 |
---|---|
07. 웹페이지 만들기(1) (0) | 2022.09.08 |
06. Redux의 장점 : 시간여행 (0) | 2022.09.06 |
05. Redux를 이용한 애플리케이션 : state의 변화를 UI에 반영 (0) | 2022.09.06 |
04. Redux를 이용한 애플리케이션 : reducer와 action을 이용해서 새로운 state 값 만들기 (0) | 2022.09.03 |