티스토리 뷰
서버에서 이런 데이터를 받아왔다고 해보자. 이 데이터를 그냥 써도 괜찮을까? 만약에 위 데이터를 가공하지 않고 그대로 사용하면 어떤 일이 벌어지는지 살펴보자.
만약에 article안에 있는 작성자의 id가 simsimjae인 article을 찾고 싶다면 아래와 같은 코드를 입력해야한다.
const id = 'simsimjae'
const articles = data.filter(article => article.author._id === id)
이정도는 괜찮다고 생각할지도 모르지만, 만약에 아래처럼 article의 comments 중 id가 simsimjae인 comment를 찾을떈?
const id = 'simsimjae'
let comments = [];
articles.forEach(article => {
article.comments.forEach(comment => {
if (comment.commenter._id === id) {
comments.push(comment);
}
})
});
데이터 하나를 찾기 위해서 이중 for문을 돌아야한다.
데이터 수가 적을땐 상관없지만 O(article수 * comment수)의 시간 복잡도를 갖기 때문에 데이터가 커질수록 시간이 점점 더 많이 걸린다.
그리고 고작 하나의 데이터를 얻기 위해 무려 9줄의 코드를 작성했다. 이런거 하나하나가 쌓이면 유지보수하기 어려운 소프트웨어를 만들게 되는것이다.
Normalizr
그래서 복잡한 구조의 데이터는 이 라이브러리를 사용해서 데이터를 참조하기 쉽고 간단하게 만들어주는게 좋다.
normalizr는 데이터를 entity의 단위로 나눈다.
위 예제에서의 entity는
users(글 작성자 or 댓글 작성자)
comments(댓글)
articles(댓글을 포함한 본문)
이다.
users entity
먼저 users에 대한 entity 만들어준다.
import { normalize, schema } from 'normalizr';
const user = new schema.Entity('users')
댓글을 단 사용자도 유저고 글을 작성한 작성자도 유저이다. 그래서 하나의 데이터 구조에서 이 두개의 유저를 굳이 다른 위치에 표현할 필요가 없다. 하나의 배열로 묶으면 된다.
comments entity
const comment = new schema.Entity('comments', {
commenter: user
})
위에서 선언한 users entity를 commenter의 엔티티로 지정했다.
comment내부에는 댓글을 작성한 commenter가 존재하고 그 commenter의 entity는 users entity다.
articles entity
const article = new schema.Entity('articles', {
comments: [comment],
author: user
})
const normalizedData = normalize(data, [article])
그리고 나서 이렇게 comment와 user entity를 묶은 article entity를 만들어 주자.
정규화된 객체(normalizedData)는 대략 이렇게 생겼다.
정확히 어떤 부분들이 바꼈는지 살펴보자.
article의 작성자 author의 id와 comment배열에 들어있는 각 comment의 작성자 id를 합쳐서 정규화 했다.
-> normalizedData.entities.comments로 전부 묶음
기존 data에서는 article의 배열이 그대로 내려왔다면
-> article들이 articles라고 하는 필드로 묶였다. 그리고 이 필드는 배열이 아닌 객체다.
그리고 기존 data에서 article 배열 안에 있는 comment가 배열 형태로 들어있었다.
-> normalizedData.entities.comments로 묶인 comment들의 아이디가 article 내부에 comment 배열로 들어가있다.
뭔가 말로 설명하기 굉장히 복잡한것같은데. 그림을 그리기는 귀찮으니 넘어간다.
그냥 한마디로 설명하면 깊게 중첩되어 있는 데이터들을 1-depth로 꺼내 모아주는 작업을 해준다고 생각하자.
'React' 카테고리의 다른 글
React Fiber가 가지는 장점 (0) | 2020.08.03 |
---|---|
React Fiber 소개 (0) | 2020.08.03 |
[ver 2020.07.27] FrontEnd Architecture(Mobx, React, React-Router) (0) | 2020.07.27 |
React Element에 $$typeof가 필요한 이유 (0) | 2020.07.20 |
[Mobx 공식문서 번역] 비동기 액션을 작성하는 방법 (0) | 2020.07.15 |
- Total
- Today
- Yesterday
- computed
- hydrate
- Polyfill
- async
- state
- reducer
- reflow
- props
- react hooks
- rendering scope
- Next.js
- javascript
- reactdom
- webpack
- es6
- Babel
- type alias
- useRef
- return type
- Action
- promise
- useEffect
- storybook
- await
- react
- atomic design
- server side rendering
- mobx
- design system
- typescript
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |