안녕하세요!

FE 개발자 유진주입니다.

Web/React

[처음 만난 리덕스] 3. Store

ypearl 2023. 12. 25. 02:55

Store

: Redux의 데이터들을 저장하기 위한 저장소

 

실제 저장이 아닌, State management의 의미

→ Redux Store의 데이터들을 저장장치에 저장되지 않음!

 

 

- Redux Store는 데이터를 어떻게 관리할까?

: JavaScript 변수를 통해 데이터를 관리

* 웹브라우저 새로고침, 컴퓨터 재부팅 시에

   Redux Store의 데이터는 모두 날아감!

 

 

- 트리 형태로 저장되는 Redux Store의 데이터들

 

 

 

 

Dispatcher

: Action을 발송하는 역할 (수신자는 Redux)

 

 

 

- Store의 dispatch 함수를 통해 디스패처 역할을 함

 

 

Store 관련 함수

  • createStore() : Redux Store를 생성하는 역할을 하는 함수

const store = creatStore(todoReducer, ['처음 만난 리덕스']);

 

  • applyMiddleware() : Middleware(미들웨어)를 적용하기 위해 필요한 함수

 

const store = createStore(todoReducer, ['처음 만난 리덕스'], applyMiddleware(loggerMiddleware));

 

  • getState() : state를 가져오는 역할을 하는 함수

- State란?
: Redux Store에 저장된 state tree

 

console.log('dispatch 이후 state', getState()); // 미들웨어 내부
console.log(store.getState()); // 미들웨어 외부

 

 

  • dispatch(action): 디스패처의 역할
store.dispatch({
	type: 'ADD_TODO',
    text: '리덕스 강의 열심히 듣기'
});

 

 

 

[실습] TODO 애플리케이션 만들기

- HTML에서 JS와 Redux만을 이용해서 진행

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h3>오늘 할 일</h3>
    <ul id="todo-list"></ul>

    <div>
        <input id="input-text"/>
        <button id="add-button">할 일 추가</button>
        <button id="logging-state">State Logging</button>
    </div>

    <script>
        function todoReducer(state, action){
            switch(action.type){
                case "ADD_TODO":
                    return state.concat(action.text);
                default:
                    return state;
            }
        }

        function loggerMiddleware({getState}){ // 구조분해할당: 파라미터 중 getState만 꺼내서 사용
            return (next) => (action) => {
                console.log("dispatch 예정 action", action);

                // Middleware chain에 있는 다음 dispatch 함수를 호출
                const returnValue = next(action);

                console.log("dispatch 이후 state", getState());

                return returnValue;
            };
        }

        var store = Redux.createStore(
            todoReducer,
            ["처음 만난 리덕스 공부하기"],
            Redux.applyMiddleware(loggerMiddleware)
        );

        var todoListElem = document.getElementById("todo-list");
        var inputElem = document.getElementById("input-text");

        function render() {
            // 이전 TODO 목록 초기화 (아이템이 중복으로 쌓이지 않기 위함)
            todoListElem.innerHTML="";

            // TODO 목록 렌더링
            store.getState().forEach((todo) => { // getState 함수: store에서 현재 state 가져옴
                // 반복문 사용해 아이템의 개수만큼 li 태그 만들어 ul 태그에 append
                const todoListItemElem = document.createElement("li");
                todoListItemElem.textContent=todo;
                todoListElem.appendChild(todoListItemElem);
            });
        }

        render();
        store.subscribe(render); // Redux Store의 state가 변경될 때마다 render 함수 호출

        document
            .getElementById("add-button")
            .addEventListener("click", function(){
                // Action을 실제로 dispatch
                store.dispatch({ // 아래 속성을 가지는 Action 객체를 만들어 dispatch
                    type: "ADD_TODO",
                    text: inputElem.value,
                });

                // Input 초기화
                inputElem.value = "";
            });
       
        document
            .getElementById("logging-state")
            .addEventListener("click", function(){
                console.log("현재 state", store.getState());
            });
    </script>
</body>
</html>

 

 

 

실행 화면