본문 바로가기

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

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

객체의 구조가 깊어지면 자바스크립트 배열 내장 함수만으로 구현할 수는 있지만 복잡해질 것이다. 가독성을 높이기 위해 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