redux 공부(생활코딩)

daewoong·2021년 7월 17일
0

redux

  • 코드의 복잡성이 높아짐 -> 코드의 복잡성을 낮추자

  • 애플리케이션의 복잡성을 낮춘다.

  • Single Source of Truth (하나의 상태)

  • state = {}에 애플리케이션에 필요한 모든 데이터를 넣는다.

  • 디스패쳐, 리듀서를 통해서만 데이터를 수정할 수 있다.

  • getState를 통해서만 데이터를 가져갈 수 있다.

리덕스가 좋은 이유

  • 컴포넌트간 의존도를 낮춰준다.
  • 로직이 적어진다.
  • 시간여행을 할 수 있다.

Redux 사용

생성, 가져오기

// 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 변경

// 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>

간단한 CRUD

<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>
profile
잘하자

0개의 댓글

관련 채용 정보