Vuex에서 상태를 정규화하는 방법
Vuex를 사용하여 앱을 개발 중인데, 네스트된 오브젝트에 대처하는 것이 귀찮은 상황이기 때문에 아래 예시와 같이 가능한 한 상태를 정상화(평탄화)하려고 합니다.
users: {
1234: { ... },
46473: { name: 'Tom', topics: [345, 3456] }
},
userList: [46473, 1234]
질문입니다.API 응답이 다음과 같을 때 위의 "최적의" 방법은 무엇입니까?
data: [
{id: 'u_0001', name: 'John', coments: [{id: 'c_001', body: 'Lorem Ipsum'}, {...}],
{id: 'u_0002', name: 'Jane', coments: [{id: 'c_002', body: 'Lorem Ipsum'}, {...}],
{...}
]
예를 들어 다음과 같이 가정하면comments
의 서브모듈입니다.users
:
옵션 1:
// action on the user module
export const users = ({ commit, state }, users) => {
commit(SET_USERS, users)
commit('comments/SET_COMMENTS', users)
}
// mutation on the user module
[types.SET_USERS] (state, users) {
state.users = users.reduce((obj, user) => {
obj[user.id] = {
id: user.id,
name: user.name,
comments: user.comments.map(comment => comment.id)
}
return obj
}, {})
state.userIds = users.map(user => user.id)
},
// mutation on the comments module
[types.SET_COMMENTS] (state, users) {
let allComments = []
users.forEach(user => {
let comments = user.comments.reduce((obj, comment) => {
obj[comment.id] = comment
return obj
}, {})
allComments.push(comments)
})
state.comments = ...allComments
},
IMO 이 옵션은 페이지(SPA/Vue-Router)를 변경할 때마다 상태를 리셋할 필요가 없기 때문에 어떤 이유로 인해 다음과 같은 상황이 발생하지 않도록 하는 것이 좋습니다.id: u_001
돌연변이가 호출될 때마다 상태가 오버라이드되기 때문에 더 이상 존재하지 않습니다만, 이 상태를 통과시키는 것은 이상하다고 느껴집니다.users array
두 돌연변이에 모두 영향을 미칩니다.
옵션 2:
// action on the user module
export const users = ({ commit, state }, users) => {
// Here you would have to reset the state first (I think)
// commit(RESET)
users.forEach(user => {
commit(SET_USER, user)
commit('comments/SET_COMMENTS', user.comments)
})
}
// mutation on the user module
[types.SET_USER] (state, user) {
state.users[user.id] = {
id: user.id,
name: user.name,
comments: user.comments.map(comment => comment.id)
}
state.userIds.push(user.id)
},
// mutation on the comments module
[types.SET_COMMENTS] (state, comments) {
comments.forEach(comment => {
Vue.set(state.comments, comment.id, comment)
})
state.commentsIds.push(...comments.map(comment => comment.id)
},
이 경우 상태를 리셋해야 합니다.그렇지 않으면 페이지를 종료하고 다시 렌더링할 때마다 반복/이전 값이 표시됩니다.Wich는 다소 짜증나고 버그나 일관되지 않은 행동에 더 유익하다.
결론: 이러한 시나리오, 어드바이스/베스트 프랙티스는 어떻게 대처하고 있습니까?저는 이런 것들에 빠져있기 때문에 답변에 매우 감사합니다.
또한 Vue ORM, Normalizr 등의 3r 파티 라이브러리는 요구가 그다지 복잡하지 않기 때문에 피하려고 합니다.
감사합니다.
PS: 테스트 없이 작성했을 뿐이므로, 코드에 오류가 있을 수 있습니다.큰 그림에 주목해 주세요.
음, 아래 주의 우발적인 복잡성을 피하기 위해 주의 정규화를 수행할 때 주의해야 할 사항입니다.
공식 Redux 문서에서 언급한 바와 같이
- 각 데이터 유형은 해당 상태에서 고유한 "테이블"을 가져옵니다.
- 각 "데이터 테이블"은 개체의 개별 항목을 저장하고 항목의 ID를 키로 항목 자체를 값으로 해야 합니다.
- 개별 항목에 대한 참조는 항목 ID를 저장하여 수행해야 합니다.
- ID 배열은 순서를 나타내는 데 사용해야 합니다.
위의 예에서 데이터에서 용장성을 제거합니다.다음과 같은 각 정보에 대해 각 테이블을 사용할 수 있습니다.users
,comments
기타 등등.
{
'users': {
byId : {
"user1" : {
username : "user1",
name : "User 1",
},
"user2" : {
username : "user2",
name : "User 2",
},
...
},
allIds : ["user1", "user2", ..]
},
'comments': {
byId : {
"comment1" : {
id : "comment1",
author : "user2",
body: 'Lorem Ipsum'
},
"comment2" : {
id : "comment2",
author : "user3",
body: 'Lorem Ipsum'
},
allIds : ["comment1", "comment2"]
}
}
이를 통해 모든 컴포넌트가 대량의 데이터 세트를 가지고 칠렌 컴포넌트에 데이터를 전달하는 대신 더 많은 컴포넌트가 접속되어 자신의 데이터 세트를 검색하고 관리하는 것을 확인할 수 있습니다.
차별 UPDATED
이후 데이터 구성 요소에 있듯이, 싱글 액션과 함께 부모 구성 요소에서 주체가 되면으로 정상화 혜택 아래 부분 달성될 수 있normalize 왔다.
- 보다 빠르고 데이터 접근보다 더 배열하거나 내포된 클레임들입니다.
- 구성 요소 사이의 느슨한 결합.
- 각 요소에 가게를, 따라서 진실의 단일 점은 자기 집이 있어요.
이 도움이 되면 좋겠어!
언급URL:https://stackoverflow.com/questions/55387562/how-to-achieve-state-normalization-in-vuex
'programing' 카테고리의 다른 글
여기서 JAVA_는MacOS Mojave(10.14)에서 Lion(10.7)으로 홈. (0) | 2022.08.28 |
---|---|
출력 스트림에 문자열 쓰기 (0) | 2022.08.28 |
고정 크기 부동 소수점 유형 (0) | 2022.08.28 |
VueJ에서는 핸섬 가능, 페이지 새로고침 시에만 테이블 로드 가능 (0) | 2022.08.28 |
v-data-table 가운데 정렬을 하나의 열만 표시 (0) | 2022.08.28 |