Computer Programming/[리액트를 다루는 기술]

React immer 라이브러리로 불변성 유지하기

Miaaaa 2023. 6. 20. 17:01

객체의 구조가 깊어지면 자바스크립트 배열 내장 함수만으로 구현할 수는 있지만 복잡해질 것이다. 가독성을 높이기 위해 immer 이라는 라이브러리를 사용하면 구조가 복잡한 객체도 쉽고 짧은 코드로 불변성을 유지하면서 데이터를 업데이트할 수 있다.

 

=> 불변성에 신경쓰지 않는 것 처럼 하지만 실제로는 불변성관리를 해주는 라이브러리.

 

 

 

 

 

yarn add immer

 

 

 

아래의 코드를 immer을 사용해서 바꿔보자

 

import { useCallback, useRef, useState } from 'react';
import './App.css';

function App() {
  const nextId = useRef(1)
  const [form, setForm] = useState({
    name: '',
    username: ''
  })
  const [data, setData] = useState({
    array: [],
    uselessData : null,
  })

  const onChange = useCallback((e) => {
    const {name, value} = e.target
    setForm({
      ...form,
      [name] : [value]
    })
  }, [form])

  const onSubmit = useCallback((e) => {
    e.preventDefault();

    const info = {
      id: nextId.current,
      name: form.name,
      username: form.username,
    }

    setData({
      ...data,
      array: data.array.concat(info)
    })
    setForm({
      name: '',
      username: '',
    })
    nextId.current += 1

  }, [data,form.name, form.username])

  const onRemove = useCallback((id) => {
    setData({
      ...data,
      array: data.array.filter(item => item.id !== id)
    })
  },[data])

  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <input name="name" value={form.name} onChange={onChange} /> 
        <input name="username" value={form.username} onChange={onChange} /> 
        <button type="submit">등록</button>
      </form>
      <div>
        <ul>
          {data.array.map((item) => {
            return (
              <li key={item.id} onClick={() => onRemove(item.id)}>
                {item.name} : {item.username}
              </li>
            )
          })}
        </ul>
      </div>
    </div>
  );
}

export default App;

 

 

아래는 immer 사용하는 법! produce를 import 해서 state (original state)을 첫번째 파라미터에, 두번째에는 값을 어떻게 바꾸고 싶은지에 대한 함수 로직을 작성하면 된다.

 

const state = {
  number: 1,
  dontChangeMe: 2
};

const nextState = produce(state, draft => {
  draft.number += 1;
});

console.log(nextState);
// { number: 2, dontChangeMe: 2 }

 

 

 

그럼 여기서의 코드를 고쳐보자면

  const onChange = useCallback((e) => {
    const {name, value} = e.target
    setForm({
      ...form,
      [name] : [value]
    })
  }, [form])

 

이렇게 draft에 [name] key 와 value value를 추가해준다.

  const onChange = useCallback((e) => {
    const { name, value } = e.target;
    setForm(
      produce(form, draft => {
        draft[name] = value
      })
    );
  }, [form])

 

 

 

 

 

https://react.vlpt.us/basic/23-immer.html

 

23. Immer 를 사용한 더 쉬운 불변성 관리 · GitBook

23. Immer 를 사용한 더 쉬운 불변성 관리 리액트에서 배열이나 객체를 업데이트 해야 할 때에는 직접 수정 하면 안되고 불변성을 지켜주면서 업데이트를 해주어야 합니다. 예를 들자면 다음과 같

react.vlpt.us