리액트를 다루는 기술 - 12장

velbie·2020년 10월 24일
0
post-thumbnail

immer

... 로 스프레드 연산자로 얕은복사 및 깊은 복사했던것을 immer를 사용하면 쉽게 할수 있습니다.
복사하는 이유는 불변성때문 입니다.

produce

11장에서 useState의 함수형 업데이트(첫 렌더링때만 함수생성 및 함수호출할때만 호출(다른거에 의해 리렌더때호출안함))에 대해 알아봤습니다.
immer에서 제공하는 produce 함수를 호출할때, 첫 번재 파라미터가 함수 형태라면 업데이트 함수를 반환합니다.!!
immer 를 써서 코드가 더러워지면 굳이 쓸 필요가 없습니다.

실습한 코드

import React, { useRef, useCallback, useState } from "react";
import produce from "immer";

const App = () => {
  const nextId = useRef(1); // 이건 로컬변수 역할이고
  const [form, setForm] = useState({ name: "", username: "" }); // 상태를 만듦 입력이랑 데이터? ㅋ 데이터에는 어레이랑 null 멀 하려는건지 ..
  const [data, setData] = useState({
    array: [],
    uselessValue: null,
  });

  // input 수정을 위한 함수 __ onChange 까지 상태관리를 해줘야 싶네 ㅡㅡ
  const onChange = useCallback(
    (e) => {
      const { name, value } = e.target; // 이거 왜 이렇게 하냐면 수정하기 귀찮아서  폼에서 많이 쓰임
      console.log("onChange");
      setForm(
        produce((draft) => {
          draft[name] = value;
        })
      );
    },
    [] // form 상태가 업데이트 될대만 !함수생성 후 실행 (리렌더링)!
  );

  // form 등록을 위한 함수
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault(); // 새로 고침 막기위해
      const info = {
        id: nextId.current,
        name: form.name,
        usename: form.username,
      };

      // array에 새 항목 등록
      setData(
        produce((draft) => {
          draft.array.push(info);
        })
      );

      // form 초기화
      setForm({
        name: "",
        username: "",
      });
      nextId.current += 1;
    },
    [form.name, form.username]
  );

  // 항목을 삭제하는 함수
  const onRemove = useCallback((id) => {
    setData(
      produce((draft) => {
        draft.array.splice(
          draft.array.findIndex((info) => info.id === id),
          1
        );
      })
    );
  }, []);

  //
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          name="username"
          placeholder="아이디"
          value={form.username}
          onChange={onChange}
        />
        <input
          name="name"
          placeholder="이름"
          value={form.name}
          onChange={onChange}
        />
        <button type="submit">등록</button>
      </form>
      <div>
        <ul>
          {data.array.map((info) => (
            <li key={info.id} onClick={() => onRemove(info.id)}>
              {info.usename} ({info.name})
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export default App;


profile
안녕하세요

0개의 댓글