728x90
반응형
불변성을 유지하면서 상태를 업데이트하는 것은 렌더링 관점에서 중요하다. 하지만 객체의 구조가 깊어지면 불변성을 유지하면서 이를 업데이트 하는 것이 어렵기 때문에 immer 라이브러리를 통해 짧게 구현할 수 있다. (필수는 아니다)
1 ) immer 설치
yarn add immer
2 ) file 생성
import {useRef, useCallback, useState} from 'react';
import './App.css';
function App() {
const nextId = useRef(1);
const [form, setForm] = useState({name: '', username: ''})
const [data, setData] = useState({
array: [],
uselessValue: 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(info => info.id !== id)
});
},
[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를 사용하면 불변성을 유지하는 작업을 간단히 처리할 수 있다.
3 ) immer를 적용한 코드
setForm 부분에서 data 저장방식을 변경한다.
import {useRef, useCallback, useState} from 'react';
import produce from 'immer';
function App() {
const nextId = useRef(1);
const [form, setForm] = useState({name: '', username: ''})
const [data, setData] = useState({
array: [],
uselessValue: null
});
const onChange = useCallback(
e => {
const {name, value} = e.target;
setForm(
produce(form, draft => {
draft[name] = value;
})
);
},
[form]
);
const onSubmit = useCallback(e => {
e.preventDefault();
const info = {
id : nextId.current,
name : form.name,
username : form.username
};
setData(
produce(data, draft => {
draft.array.push(info);
}
));
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;
728x90
반응형
'Programming > React.js' 카테고리의 다른 글
12. ContextApi (0) | 2022.09.14 |
---|---|
11. 라우터로 SPA 개발하기 (0) | 2022.09.08 |
9. 컴포넌트 성능 최적화 (0) | 2022.08.24 |
8. Component styling (0) | 2022.03.08 |
7. Hooks (0) | 2022.03.06 |