728x90
- 구조가 복잡한 객체도 매우 쉽고 짧은 코드를 사용하여 불변성을 유지하며 업데이트가 가능하다.
펼침연산자(...)를 자주 사용하여 기존값은 유지하되 원하는 값을 새로 지정하면 코드가 복잡해진다.
1. immer 사용법
- immer를 사용하지 않고 불변성 유지
...(펼침연산자)를 이용하다 보니 가시성이 떯어지고 코드가 복잡해진다.
- 사용법
import produce from 'immer';
const nextState = produce(originalState, draft => {
draft.somewhere.deep.inside = 5;
});
- produce 함수는 2가지 파라미터를 받는다.
- 첫번째는 수정하고 싶은 상태
- 두번째는 상태를 어떻게 업데이트할 지 정의하는 함수
- 두번째 파라미터로 전달되는 함수 내부에서 원하는 값을 변경하려면
produce함수가 불변성 유지를 대닛해 주면서 새로운 상태를 생성해준다.
immer라이브러리의 핵심 : "불변성을 제대로 관리해주는 것" 이다.
- App 컴포넌트에 immer 적용하기
immer를 사용하면 컴포넌트 작성할 때는 객체 안에 있는 값을 직접 수정하거나,
배열에 직접적인 변화를 일으키는 push, splish 등의 함수를 사용해도 무관하다.
import { useRef, useCallback, useState } from 'react';
//immer 사용
import produce from 'immer';
const App = () => {
const nextId = useRef(1);
const [form, setForm] = useState({ name: '', username: '' });
const [data, setData] = useState({
array: [],
uselessValue: null,
});
// input 수정을 위한 함수
const onChange = useCallback(
e => {
const { name, value } = e.target;
setForm(
// produce함수 호출 시 첫번째 파라미터가 함수 형태라면 업데이트 함수를 반환하여 깔끔한 코드 작성 가능
produce(form, draft => {
draft[name] = value;
})
);
},
[] //
);
// form 등록을 위한 함수
const onSubmit = useCallback(
e => {
e.preventDefault();
const info = {
id: nextId.current,
name: form.name,
username: form.username,
};
// array에 새 항목 생성
setData(
produce(data, draft => {
draft.array.push(info);
})
);
// form 초기화
setForm({
name: '',
username: '',
});
nextId.current += 1;
},
[form.name, form.username]
);
// 항목을 삭제하는 함수
const onRemove = useCallback(
id => {
setData(
produce(data, draft => {
draft.array.splice(draft.array.findIndex(info => info.id === id), 1);
})
);
},
[]
);
return (
...
)
};
export default App;
- useState의 함수형 업데이트와 immer 함께쓰기
immer에서 저공하는 produce 함수 호출 시 첫번째 파라미터가 함수 형태라면 업데이트 함수를 반환한다.
→ immer의 속성과 useState의 함수형 업데이트를 같이 사용하면 더 깔끔해진다.
import { useRef, useCallback, useState } from 'react';
//immer 사용
import produce from 'immer';
const App = () => {
const nextId = useRef(1);
const [form, setForm] = useState({ name: '', username: '' });
const [data, setData] = useState({
array: [],
uselessValue: null,
});
// input 수정을 위한 함수
const onChange = useCallback(
e => {
const { name, value } = e.target;
setForm(
// produce함수 호출 시 첫번째 파라미터가 함수 형태라면 업데이트 함수를 반환하여 깔끔한 코드 작성 가능
produce(draft => {
draft[name] = value;
})
);
},
[] //
);
// form 등록을 위한 함수
const onSubmit = useCallback(
e => {
e.preventDefault();
const info = {
id: nextId.current,
name: form.name,
username: 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 (
...
)
};
export default App;
728x90
'React' 카테고리의 다른 글
React) 14장 외부 API를 이용한 뉴스 뷰어 (0) | 2022.05.10 |
---|---|
React) 13장 리액트 라우터로 SPA개발하기 (0) | 2022.05.07 |
React) 11장 컴포넌트 최적화 (0) | 2022.04.19 |
React) 10장 TodoList 프로젝트 (0) | 2022.04.17 |
React) 9장 컴포넌트 스타일링 (0) | 2022.04.16 |