프로그래밍/TIL

TIL - useReducer 를 사용하여 배열에 값을 추가할때!

삐제제 2021. 8. 30. 02:16

 

import React, { useReducer, useState } from "react";

const initialState = {
  toDos: [],
};
const ADD = "add";

const reducer = (state, action) => {
  switch (action.type) {
    case ADD:
      return { toDos: [...state.toDos, { text: action.payload }] };
    default:
      throw new Error();
  }
};

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState);
  const [newToDo, setNewToDo] = useState("");
  const onSubmit = (e) => {
    e.preventDefault();
    dispatch({ type: ADD, payload: newToDo });
    setNewToDo("");
  };

  const onChange = (e) => {
    const { value } = e.target;
    setNewToDo(value);
  };

  return (
    <>
      <h1>Add to Do</h1>
      <form onSubmit={onSubmit}>
        <input
          value={newToDo}
          type="text"
          placeholder="Write to do"
          onChange={onChange}
        ></input>
      </form>
      <ul>
        <h2>To Dos</h2>
        {state.toDos.map((toDo, index) => (
          <li key={index}>{toDo.text}</li>
        ))}
      </ul>
    </>
  );
};

export default App;

오늘 useReducer를 사용한 간단한 투 두 리스트 구현하는걸 배우는 도중 이해가 안가는 부분이 생겼다.

 

useReducer를 사용하여 state를 변경하는것, 특히 그 state가 배열이고 새로운 데이터를 배열안에 넣을때의 방식에 관한 것이었는데, push처럼 직접 state배열에 집어넣는게 아니라, 상태를 교체? 하는 방식으로 집어넣는다고 한다.

 

내가 처음에 한 생각은, 교체를 하는데 어떻게 리스트를 만들수 있을까? 말 그대로 상태를 교체하는건데 배열에 값 추가를 어떻게 하지? 라는 의문도 생기고 코드를 보면서도 끙끙댄거같다.

 

콘솔에도 찍어보고 나름 구조를 이해하려고 노력한 결과 어떤 원리인지 이해했다!

 

내가 이해를 잘 못한 코드의 구문은 다음 코드인데,

      return { toDos: [...state.toDos, { text: action.payload }] };

여기서 ...state.toDos 의 역할을 잘 이해하지 못했었다. 근데 다만 이게 없으면 리스트에 추가가 안된다는것..?!

그리고 이 예제뿐만아니라, 객체로 이루어진 state를 변경할때도 spread operator를 이용하여, state객체를 복사하고 그 이후에 키값에 접근하여 변경하는 코드들도 종종 보았었다.

 

아무튼 여기서 ...state.toDos의 역할은, 보시다싶이 state.toDos 배열을 복붙하는 역할이다.

 

왜 복붙을 해야할까? 

-> 복붙하지 않으면 리스트를 추가 할 수 없다.

 

이게 어떤식으로 동작하는지 내가 이해한대로 써보자면,

처음, toDos 배열은 빈 배열일것이다. 그리고 글을 입력하고 엔터를 눌렀을때

reducer에서 return 하는건 text 뿐일테고, 그러면 state.toDos에 방금 입력한 텍스트가 배열안에 들어갈 것이다. 그리고 이게 state.toDos를 의미하게 되는거고,

 

이제 두번째로 텍스트를 입력한다고 생각했을때,

      return { toDos: [...state.toDos, { text: action.payload }] };

여기 ...state.toDos에는 방금 처음 입력한 text가 들어가 있을것이다.

즉 어떤 상태냐면

      return { toDos: [{text: "Hello"}, { text: action.payload }] };

이런 상태일것이다. 그리고 이것을 리턴해주니 당연히 state.toDos는 [ {text: "Hello"}, {text:"방금입력한텍스트"} ] 이렇게 될것이다. 그래서 글을 입력하면 계속 리스트가 추가될 수 있는것이다! 

 

상태를 "교체" 하는 방식으로 데이터를 추가한다.. 라는 의미를 오늘 어느정도는 이해한것 같다.

'프로그래밍 > TIL' 카테고리의 다른 글

TIL - React - thunk 라이브러리  (0) 2021.09.15