Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 자바스크립트
- webProject
- Props
- REACT
- 비동기함수
- 함수 실행
- JavaScript
- 이벤트핸들링
- callback함수
- 메소드 실행
- CSS
- 리액트
- input
- 배열
- useRef
- 배열메소드
- 이벤트
- frontendstudy
- addEventListener
- FrontendStydy
- DOM
- typeScript
- promise
- HTML
- Frontend Study
- this 객체
- 렌더링
- try.. catch
- 컴포넌트
- useState
Archives
- Today
- Total
이다닷
[React] Day 25 - Immer를 사용한 더 쉬운 불변성 관리 본문
📢리액트에서 배열이나 객체를 업데이트 해야 할 때에는 직접 수정하면 안되고, 불변성을 지켜주면서 업데이트 해주어야 한다. -> 지금까지 사용했던 확장 연산자를 사용하면 된다.
ex)
const num = {
a: 1,
b: 2
};
num.b = 3;
이렇게 하면 안되고,
const num = {
a: 1,
b: 2
};
const nextNum = {
...object,
b: 3
};
이렇게 해주어야 한다.
📌배열도 마찬가지로 항목을 직접 수정하면 안되고, concat, filter, map 등의 함수를 사용해야한다.
이 외에 상황에서 데이터의 구조가 조금 까다로워지면 불변성을 지켜가면서 새로운 데이터를 생성해내는 코드가 조금 복잡해질때가 있다.
ex)
const state = {
posts: [
{
id: 1,
title: '제목입니다.',
body: '내용입니다.',
comments: [
{
id: 1,
text: '와 정말 잘 읽었습니다.'
}
]
},
{
id: 2,
title: '제목입니다.',
body: '내용입니다.',
comments: [
{
id: 2,
text: '또 다른 댓글 어쩌고 저쩌고'
}
]
}
],
selectedId: 1
};
const nextState = {
...state,
posts: state.posts.map(post =>
post.id === 1
? {
...post,
comments: post.comments.concat({
id: 3,
text: '새로운 댓글'
})
}
: post
)
};
-> 이렇게 복잡해질 수 있다.
📌이럴때, immer이라는 라이브러리를 사용하면 쉽게 구현할 수 있다.
위에 있는 코드를 예시로 바꿔보면, 이렇게 짧아지는 것을 볼 수 있다.
const state = {
number: 1,
dontChangeMe: 2
};
const nextState = produce(state, draft => {
draft.number += 1;
});
console.log(nextState);
우리의 APP.js라는 코드를 변경시켜볼 수 있다.
APP.js 변경
import React, { useReducer, useMemo } from 'react';
import UserList from './qoffhvjxm/UserList';
import CreateUser from './qoffhvjxm/CreateUser';
import produce from 'immer';
function countActiveUsers(users) {
console.log('활성 사용자 수를 세는중...');
return users.filter(user => user.active).length;
}
const initialState = {
users: [
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]
};
function reducer(state, action) {
switch (action.type) {
case 'CREATE_USER':
return produce(state, draft => {
draft.users.push(action.user);
});
case 'TOGGLE_USER':
return produce(state, draft => {
const user = draft.users.find(user => user.id === action.id);
user.active = !user.active;
});
case 'REMOVE_USER':
return produce(state, draft => {
const index = draft.users.findIndex(user => user.id === action.id);
draft.users.splice(index, 1);
});
default:
return state;
}
}
export const UserDispatch = React.createContext(null);
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
const { users } = state;
const count = useMemo(() => countActiveUsers(users), [users]);
return (
<UserDispatch.Provider value={dispatch}>
<CreateUser />
<UserList users={users} />
<div>활성사용자 수 : {count}</div>
</UserDispatch.Provider>
);
}
export default App;
좋은 부분도 있지만, 오히려 immer을 사용해서 복잡해지는 경우도 있다. 그리고, immer은 좋은 라이브러리지만 성능적으로는 immer을 사용하지 않은 코드가 조금 더 빠르다. 따라서 적절하게 사용하면 좋은 라이브러리이다.
'React' 카테고리의 다른 글
[React] Day 27 - LifeCycle Method (0) | 2023.10.10 |
---|---|
[React] Day 26 - 클래스형 컴포넌트 (0) | 2023.10.09 |
[React] Day 24 - Context API를 사용한 전역 값 관리 (0) | 2023.10.03 |
[React] Day 23 - 커스텀 Hooks 만들기 (2) | 2023.10.02 |
[React] Day 22 - useReducer를 사용하여 상태 업데이트 로직 분리하기 (0) | 2023.09.30 |