프론트엔드 첫걸음

immer 사용법 본문

개발 공부/React

immer 사용법

차정 2022. 8. 29. 11:03
리액트를 다루는 기술 12장

 

1. immer 설치

yarn add immer 

 

2.  immer 사용

첫번째 파라미터로 수정하고 싶은 상태, 두번째 파라미터로 상태를 어떻게 업데이트할지 정의하는 함수를 받는다.
두번째 파라미터로 전달되는 함수 내부에서 원하는 값을 변경하면 , immer 함수가 불변성 유지를 대신하면서 새로운 상태를 생성해준다.

import prodece from 'immer';

const nextState = produce(originalState, draft => {
	draft.somewhere.deep.inside 5;f
	
})

 

 

3. immer 사용 예시

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

const App = () => {
  const [form, setForm] = useState({ name: '', username: '' });
  const [data, setData] = useState({ array: [], uselessValue: null });

  const nextId = useRef(1);

  //input 수정을 위한 함수
  const onChange = useCallback(
    (e) => {
      const { name, value } = e.target;
      setForm(
      //immer 없이 불변성유지 
        // { ...form,
        // [name]: [value] }

      //immer 사용
       produce(form, (form) => {
          form[name] = value;
        })
      );
    },
    [form]
  );

  //form 등록을 위한 함수
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault();
      const info = {
        id: nextId.current,
        name: form.name,
        username: form.username,
      };

      // array에 새 항목 등록
      setData(
        //immer 없이 불변성유지 
        //  { ...data, array: data.array.concat(info) }

        //immer 사용
        produce(data, (data) => {
          data.array.push(info);
        })
      );

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


  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          name='username'
          placeholder='아이디'
          value={form.username}
          onChange={onChange}
        />     
        <button type='submit'>등록</button>
      </form>    
    </div>
  );
};

export default App;

 

 

4. immer에 함수형 setState를 파라미터로 받게 하기

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

const App = () => {
  const [form, setForm] = useState({ name: '', username: '' });
  const [data, setData] = useState({ array: [], uselessValue: null });

  const nextId = useRef(1);

  //input 수정을 위한 함수
  const onChange = useCallback(
    (e) => {
      const { name, value } = e.target;
      setForm(
      //immer 없이 불변성유지 
        // { ...form,
        // [name]: [value] }

      //immer 사용
      // produce(form, (form) => {
      
      produce((form) => {    //immer+useState함수형 업데이트
       form[name] = value;
        })
      );
    },
   //  [form]
    []   //상태 form대신 함수받으니까 의존성배열에 form 넣을 필요 없음 
  );

  //form 등록을 위한 함수
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault();
      const info = {
        id: nextId.current,
        name: form.name,
        username: form.username,
      };

      // array에 새 항목 등록
      setData(
        //immer 없이 불변성유지 
        //  { ...data, array: data.array.concat(info) }

		//immer 사용
        //  produce(data, (data) => {
        produce((data) => {
        data.array.push(info);
        })
      );

      //form 초기화
      setForm({
        name: '',
        username: '',
      });
      nextId.current++;
    },
    //[data, form.name, form.username]
     [form.name, form.username] //상태 data안받고 함수받으니까 data를 의존할 필요없음
  
   );


  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          name='username'
          placeholder='아이디'
          value={form.username}
          onChange={onChange}
        />     
        <button type='submit'>등록</button>
      </form>    
    </div>
  );
};

export default App;

 

'개발 공부 > React' 카테고리의 다른 글

[문제해결] 중괄호와 괄호 헷갈리지 않게 잘 쓰기  (0) 2022.08.30
ContextAPI  (0) 2022.08.30
불변성을 지키면서 setState  (0) 2022.08.28
Todo App 성능개선 (React.memo + 함수형 setState)  (0) 2022.08.28
Redux  (0) 2022.08.23