Redux | Review Redux (with Vanilla JS & React)

kihyeon8949·2021년 1월 17일
0

Redux

목록 보기
1/1

Redux를 프로젝트에 적용하기에 앞서 간단한 코드를 통해서 복습하였다.
( Vanilla JS + Redux 조합을 사용해보는것도 Redux를 이해하는데 있어서 도움이 되었다. )

1. Redux - Vanilla JS

Counter

  • index.html
  <body>
    <button id="add">Add</button>
    <span></span>
    <button id="minus">Minus</button>
  </body>
  • index.js
import { createStore } from "redux";

const add = document.getElementById("add");
const minus = document.getElementById("minus");
const number = document.querySelector("span");
number.innerText = 0;

// 🌟 reducer is func and 🌟 ONLY Reducer can control(modify) datas(states)!
// 🌟 reducer가 return하는건 app의 state(data)이다, 여야한다.
// (currnet state or initial state, action)

//2. 리듀서 생성
const countModifier = (count = 0, action) => {
  //5. 입력받은 action객체의 타입에 따라 state를 조작하여 리턴
  switch (action.type) {
    case "ADD":
      return count + 1;
    case "MINUS":
      return count - 1;
    default:
      return count;
  }
};

//1. 스토어 생성 후
//3. 생성된 reducer를 전달
const countStore = createStore(countModifier);

const onChange = () => {
  number.innerText = countStore.getState();
};
countStore.subscribe(onChange);

//4.reducer의 두번째 인자로 들어가는 action객체는 disaptch를 통해서 reducer로 전달!
//action은 오브젝트 이다! 항상 "type"을 가져야하고, 그 키 값은 바뀔 수 없다.


const handleAdd = () => {
  countStore.dispatch({ type: "ADD" });
};

const handleMinus = () => {
  countStore.dispatch({ type: "MINUS" });
};

add.addEventListener("click", handleAdd);
minus.addEventListener("click", handleMinus);

// type을 const ADD = "ADD" 으로 정의하고 사용하게된다면 오류가 났을 때 정확히 판단할 수 있을 것이다.
//(js가 오류를 어디서 오류가 났는지 알려줄거야...)

To Do Lists - Vanilla JS

  • index.html
<form>
      <input type="text" placeholder="Write to do" />
      <button>Add</button>
    </form>
    <ul></ul>
  • index.js
//// To Dos ////

const form = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul");

//action type
const ADD_TODO = "ADD_TODO";
const DELETE_TODO = "DELETE_TODO";

//action creator
const addToDo = text => {
  return { type: ADD_TODO, text };
};
const deleteToDo = id => {
  return { type: DELETE_TODO, id };
};

//reducer
// mutate -> X create -> O
const reducer = (state = [], action) => {
  // console.log(action);
  switch (action.type) {
    case ADD_TODO:
      //새로운 todo 오브젝트 생성
      const newToDoObj = { text: action.text, id: Date.now() };
      return [newToDoObj, ...state];
    case DELETE_TODO:
      // filter을 이용하여 state를 변경하는 것이 아닌 새로운 배열을 리턴한다
      return state.filter(toDo => toDo.id !== action.id);
    default:
      return state;
  }
};

//store생성
const store = createStore(reducer);

//dispatch
const dispatchAddToDo = text => {
  store.dispatch(addToDo(text));
};
const dispatchDeleteToDo = e => {
  const id = parseInt(e.target.parentNode.id);
  store.dispatch(deleteToDo(id));
};

//subscribe의 listener
const paintToDos = () => {
  const toDos = store.getState();
  ul.innerHTML = "";
  toDos.forEach(toDo => {
    const li = document.createElement("li");
    const btn = document.createElement("button");
    btn.innerText = "delete";
    btn.addEventListener("click", dispatchDeleteToDo);
    li.id = toDo.id;
    li.innerText = toDo.text;
    li.appendChild(btn);
    ul.appendChild(li);
  });
};

//subscribe
store.subscribe(paintToDos);

const onSubmit = e => {
  e.preventDefault();
  const toDo = input.value;
  input.value = "";
  dispatchAddToDo(toDo);
};

form.addEventListener("submit", onSubmit);

2. Redux - React

To Do Lists - React

  • index.js
//// React Redux
ReactDOM.render(
  <Provider store={store}>
    <App></App>
  </Provider>,
  document.getElementById("root")
);
  • home.jsx
const Home = ({ toDos, addToDo }) => {
  const formRef = React.createRef();
  const inputRef = React.createRef();

  const onSubmit = event => {
    event.preventDefault();
    const text = inputRef.current.value;
    text && addToDo(text);
    formRef.current.reset();
  };

  return (
    <>
      <h1>To Dos </h1>
      <form ref={formRef} onSubmit={onSubmit}>
        <input ref={inputRef} type="text" />
        <button>Add</button>
      </form>
      <ToDos toDos={toDos} />
    </>
  );
};

//순수함수, 동기적
const mapStateToProps = (state, ownProps) => {
  return { toDos: state };
};

const mapDispatchToProps = dispatch => {
  return {
    addToDo: text => dispatch(actionCreater.addToDo(text)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);
  • todos.jsx
const ToDos = ({ toDos }) => {
  return (
    <ul>
      {toDos.map(toDo => {
        return <List toDo={toDo} key={toDo.id} />;
      })}
    </ul>
  );
};

export default ToDos;
  • list.jsx
const List = ({ toDo, deleteToDo }) => {
  const deleteList = () => {
    deleteToDo(toDo.id);
  };

  return (
    <li>
      {toDo.text}
      <button onClick={deleteList}>delete</button>
    </li>
  );
};

const mapDispatchToProps = dispatch => {
  return {
    deleteToDo: id => dispatch(actionCreater.deleteToDo(id)),
  };
};

export default connect(null, mapDispatchToProps)(List);
profile
함께 일하고 싶은 개발자를 목표로 매일을 노력하고, 옷을 좋아하는 권기현 입니다.

0개의 댓글