Redux 내부에 관계형 데이터를 저장하는 방법
20025 단어 reactpatternsreduxjavascript
사진 제공: Tobias Fischer on Unsplash
조만간 모든 프런트엔드 개발자는 관계형 데이터를 Redux 스토어에 저장해야 합니다.
TL; DR
Firebase의 advice을 따르십시오. 매우 유용합니다.
데이터
관계형 DB를 기반으로 하는지 여부에 관계없이 데이터는 그들 사이에 관계가 있습니다.
우리는 다른 리소스와 관계를 가질 수 있는 모든 유형의 데이터를 리소스로 정의할 것입니다.
예제 리소스는 개인 블로그의 게시물일 수 있습니다.
이 게시물은 작성자와 1:1 관계(게시물 관점에서 볼 때 작성자는 게시물과 1:N 관계가 됨)와 댓글과 1:N 관계가 됩니다.
비효율적인 구조
개인 블로그가 게시물 목록과 게시물 각각에 대한 세부 정보 페이지만 표시해야 한다고 가정해 보겠습니다.
이 특정 예의 경우 Redux 스토어에서 id로 인덱싱된 모든 게시물을 포함하는 첫 번째 수준 키를 가질 수 있습니다. 각각 안에 저자의 데이터와 의견을 내포할 수 있습니다.
const store = {
posts: {
'p123': {
id: 'p123',
title: 'Best React pattern in the world!',
author: {
id: 'a123',
name: 'Francesco',
email: '[email protected]',
},
comments: {
'c123': {
id: 'c123',
body: 'Best article ever!',
},
'c124': {
id: 'c124',
body: 'Best article ever ever!',
},
}
},
}
}
// And so on, you get the point
작성자의 게시물 목록이 포함된 작성자 프로필 페이지를 만들려는 경우 문제가 발생합니다.
Redux 선택자를 예로 들면 다음과 같은 방법으로 필요한 데이터를 검색할 수 있습니다.
// This returns an array of posts
const getPostsByAuthor = authorId => state => (
Object.values(state.posts).filter(post => post.author.id === authorId)
)
// And you'd call this selector like this:
const state = store.getState()
const postsByAuthor = getPostsByAuthor('a123')(state) // [...]
그러나 우리가 필요한 것을 얻을 수 있는 것은 특히 비효율적일 것입니다. 매번 모든 게시물을 검토해야 합니다.
가중 구조
가중 구조는 관계형 DB 내 가상 테이블의 1:1 표현일 수 있습니다.
const store = {
posts: {
'p123': {
id: 'p123',
title: 'Best React pattern in the world!',
author: 'a123',
},
},
author_posts: {
'a123': ['p123'],
},
authors: {
'a123': {
id: 'a123',
name: 'Francesco',
email: '[email protected]',
}
},
post_comments: {
'p123': ['c123', 'c124'],
},
comments: {
'c123': {
id: 'c123',
body: 'Best article ever!',
post: 'p123',
},
'c124': {
id: 'c124',
body: 'Best article ever ever!',
post: 'p123',
},
},
}
이 경우 중첩 문제를 제거했습니다. 그러나 Redux 스토어에 두 개의 새로운 첫 번째 수준 키를 추가했습니다.
이 접근 방식이 완전히 잘못된 것은 아니지만 애플리케이션이 커짐에 따라 모든 관계를 효율적으로 관리하기 어려울 수 있습니다.
리소스의 양이 제한되어 있는 경우 유용한 접근 방식이 될 수 있습니다. 그러나 리소스의 양이 제한되어 있으면 Redux가 실제로 필요하지 않을 수도 있습니다.
효율적인 구조
Firebase의 권장 사항에 따라 몇 가지 첫 번째 수준 키를 저장할 수 있습니다.
const store = {
posts: {
data: {
'p123': {
id: 'p123',
title: 'Best React pattern in the world!',
author: 'a123',
},
},
comments: {
'p123': ['c123', 'c124'],
},
},
authors: {
data: {
'a123': {
id: 'a123',
name: 'Francesco',
email: '[email protected]',
},
},
posts: {
'a123': ['p123'],
},
},
comments: {
data: {
'c123': {
id: 'c123',
body: 'Best article ever!',
post: 'p123',
},
'c124': {
id: 'c124',
body: 'Best article ever ever!',
post: 'p123',
},
},
},
}
Firebase와 달리 "자리 표시자"와 관계를 중첩하지 않습니다.
대신 첫 번째 수준 키를 작은 두 번째 수준 저장소 컨테이너로 구성합니다.
reducers
및 combineReducers
함수에 대해 비슷한 생각을 하고 있습니까? 동일한 논리: 전역 개체를 표현할 수 있는 가장 작은 부분으로 줄입니다.보너스: 선택자를 구성하는 방법
Redux 스토어를 구성한 후 가장 먼저 떠오를 수 있는 질문은 이 데이터를 어떻게 얻을 수 있습니까?
다음은 간단한 선택자입니다.
// Base data
const selectAuthors = state => Object.values(state.authors.data)
const selectAuthor = id => state => state.authors.data[id]
const selectPosts = state => Object.values(state.posts.data)
const selectPost = id => state => state.posts.data[id]
// Totally useless
const selectComments = state => Object.values(state.comments.data)
// Maybe useless
const selectComment = id => state => state.comments.data[id]
// Relations
const selectAuthorPosts = authorId => state => {
const authorPosts = state.authors.posts[authorId] || []
return authorPosts.map(postId => selectPost(postId)(state))
}
const selectPostComments = postId => state => {
const postComments = state.posts.comments[postId] || []
return postComments.map(commentId => selectComment(commentId)(state))
}
결론
이제 Redux 저장소를 구성하여 관계형 데이터를 저장할 수 있습니다. 어떤 경우에는 과잉일 수 있지만 더 복잡한 응용 프로그램을 처리하는 데 유용합니다.
게시물이 마음에 드셨다면 🦄를 남겨주세요!
Reference
이 문제에 관하여(Redux 내부에 관계형 데이터를 저장하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pigozzifr/how-to-store-relational-data-inside-redux-el6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)