Reputation: 4349
I am trying to create a React/Redux app which lists books. Each book then has related books. I know I should structure my redux store in some sort of normalized fashion like so:
{
books: {
'book1id': {
title: 'Book 1',
author: 'Author 1',
relatedBooks: ['book2id', 'book3id']
},
'book2id': {
title: 'Book 2',
author: 'Author 2',
relatedBooks: ['book1id']
}
}
}
and load each book as necessary.
The issue is where to store loading/error data from the API requests? Some ideas I had were to create an object for every book such as
books: {
'book1id': {
isLoading: false,
error: null,
book: {
title: 'Book 1',
...
}
},
...
}
But that seems to detract slightly from the readability/intuitiveness of the state. Is there a better way to structure the state?
Upvotes: 2
Views: 741
Reputation: 26
I structure my redux store so that it includes an entities object for all of my relational data and I store things specific to a page or a set of routes in separate parts of the state. My state tree might look something like this:
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
isLoading: false
}
}
Now I am keeping track of my relational state separate from the state of my UI components. I would not recommend trying to store a isLoading
state in an individual entity since that entity may or may not exist. If you need more granular loading/error state on a per entity basis then rather on a set of entities you have a few options. The first option is keep a set of IDs that are currently loading. This is not a very practical solution because you can't track success or failure with an ID simply being in a set or not.
The next, better solution is to keep a map from ID to a status object that includes if an individual entity is loading, if it was successful or if it failed to load and what the errors were.
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
loading: {
book1: {
status: 'FAILED',
error: 'Network request failed.'
},
book2: {
status: 'SUCCESS',
},
book3: {,
status: 'IN_PROGRESS'
}
}
}
}
In summary, I find separating out your relational state into an entities child object while having page specific sections of state to be working quite well for me.
Upvotes: 1