React.memo
에서 서로 비교하여 최적화하는 것이 불가능하다.
const object = {
somewhere: {
deep: {
inside: 3,
array: [1, 2, 3, 4]
},
bar: 2
},
foo: 1
};
// somewhere.deep.array에 5 추가
let nextObject = {
...object,
somewhere: {
...object.somewhere,
depp: {
...object.somewhere.deep,
array: object.somewhere.deep.array.concat(5)
}
}
};
immer
라이브러리를 사용하면, 구조가 복잡한 객체도 매우 쉽고 짧은 코드를 사용하여 불변성을 유지하면서 업데이트 할 수 있다.불변성을 신경 쓰지 않는 것처럼 코드를 작성하지만 불변성 관리를 제대로 해준다.
단순히 깊은 곳에 위치하는 값을 변경하는 것 외 배열을 처리할 때도 매우 유용.
yarn add immer
import produce from 'immer';
const nextState = produce(originalState, draft => {
// 바꾸고 싶은 값 바꾸기
draft.somewhere.deep.inside = 5;
});
produce(수정하고 싶은 상태, 상태 변경을 정의하는 함수)
import produce from "immer";
import { useCallback, useState, useRef } from "react";
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(form, (draft) => {
draft[name] = value;
})
);
},
[form]
);
// 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;
},
[data, form.name, form.username]
);
// 항목을 삭제하는 함수
const onRemove = useCallback(
(id) => {
setData(
produce(data, (draft) => {
draft.array.splice(
draft.array.findIndex((info) => info.id === id),
1
);
})
);
},
[data]
);
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.username} ({info.name})
</li>
))}
</ul>
</div>
</div>
);
};
export default App;
immer
라이브러리는 컴포넌트 상태 업데이트가 조금 까다로울 때 사용하면 매우 좋다.Redux
를 사용할 때도 immer를 쓰면 코드를 매우 쉽게 작성할 수 있다.immer
사용이 불편하게 느껴진다면 사용하지 않아도 좋다.