... 로 스프레드 연산자로 얕은복사 및 깊은 복사했던것을 immer를 사용하면 쉽게 할수 있습니다.
복사하는 이유는 불변성때문 입니다.
11장에서 useState의 함수형 업데이트(첫 렌더링때만 함수생성 및 함수호출할때만 호출(다른거에 의해 리렌더때호출안함))에 대해 알아봤습니다.
immer에서 제공하는 produce 함수를 호출할때, 첫 번재 파라미터가 함수 형태라면 업데이트 함수를 반환합니다.!!
immer 를 써서 코드가 더러워지면 굳이 쓸 필요가 없습니다.
실습한 코드
import React, { useRef, useCallback, useState } from "react";
import produce from "immer";
const App = () => {
const nextId = useRef(1); // 이건 로컬변수 역할이고
const [form, setForm] = useState({ name: "", username: "" }); // 상태를 만듦 입력이랑 데이터? ㅋ 데이터에는 어레이랑 null 멀 하려는건지 ..
const [data, setData] = useState({
array: [],
uselessValue: null,
});
// input 수정을 위한 함수 __ onChange 까지 상태관리를 해줘야 싶네 ㅡㅡ
const onChange = useCallback(
(e) => {
const { name, value } = e.target; // 이거 왜 이렇게 하냐면 수정하기 귀찮아서 폼에서 많이 쓰임
console.log("onChange");
setForm(
produce((draft) => {
draft[name] = value;
})
);
},
[] // form 상태가 업데이트 될대만 !함수생성 후 실행 (리렌더링)!
);
// form 등록을 위한 함수
const onSubmit = useCallback(
(e) => {
e.preventDefault(); // 새로 고침 막기위해
const info = {
id: nextId.current,
name: form.name,
usename: 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 (
<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.usename} ({info.name})
</li>
))}
</ul>
</div>
</div>
);
};
export default App;