Let's say you have a book application using Redux with a few features:
Now let's say that all of these different modules, and a common feature across all these modules is the ability to search for books (i.e. searching for books to buy, books to add to a wishlist, books to review, etc).
These search results will be stored across multiple slices of the state tree.
An example of the state tree might look like this:
{
bookStore: {
booksSearchResults: [],
...,
},
wishlist: {
booksSearchResults: [],
...,
},
reviews: {
newReview: {
booksSearchResults: [],
...,
},
...
},
...
}
Are there any best practices around managing such things? Would it be simply to have a booksSearch
slice of state and manage that through a shared component?
How about cases where you might need to search for books in multiple places on the same screen (i.e. you might have an autocomplete search feature in the nav bar in addition to a search component in the main part of the application)?
Is another approach to reuse the search logic and somehow have it update different parts of the state (and if so, does something exist to achieve this)?
For that, Redux Persist includes the PersistGate component. To use PersistGate , go to the index. js file in the src directory and add the following import: // src/index.
Redux restricts updating the state to this method only. This strict way of updating the state ensures that the state can not be changed directly either by view or any network callback. The only way to update a state is by defining the action and then dispatching it. Remember that actions are plain JavaScript objects.
The way Redux works is simple. There is a central store that holds the entire state of the application. Each component can access the stored state without having to send down props from one component to another. There are three core components in Redux — actions, store, and reducers.
As mentioned above, state in Redux is read-only. This helps you restrict any part of the view or any network calls to write/update the state directly. Instead, if anyone wants to change the state of the application, then they'll need to express their intention of doing so by emitting or dispatching an action.
I have two pieces of advice for you:
This is well documented, so I won't go too deep into it here. Suffice it to say that normalizing your store will be flexible and help you to reason about your app. Think of your store as you would a server-side database and it will be more reusable than if you were to tailor each section of the state to your views.
One way you could do this for your app:
{
books: {
bookId: {
bookDetails,
reviews: [ reviewId ],
ownedBy: [ userId ],
wishlistedBy: [ userId ],
recommendations: [ recommendationId ]
}
},
users: {
userId: {
userDetails,
reviews: [ reviewId ],
wishlist: [ bookId ],
ownedBooks: [ bookId ],
friends: [ userId ],
sentRecommendations: [ recommendationId ],
receivedRecommendations: [ recommendationId ]
}
},
reviews: {
reviewId: {
bookId,
userId,
reviewDetails
}
},
recommendations: {
recommendationId: {
sender: userId,
recipient: userId,
bookId,
recommendationDetails
}
}
}
You may not need all of those relationships, so don't feel like you have to implement all of that. But starting with a base similar to this will make it much easier to add features later.
Resources:
Search results are more of a view detail than a data concern. You may need to store a historical record of searches, and in that case, you could add a reducer for searches:
{
searches: [
{
searchTerm,
searchDetails
}
]
}
But even in that case, I don't think I would store the search results. Storing results will limit functionality in a couple cases.
So, I consider results a view detail--or, as James K. Nelson calls it, "Control State" (read: The 5 Types of React Application State). Your question doesn't say which view library (if any) you're using, but the concepts here should be applicable regardless of whether you're using React or not.
Search results should be calculated by the view. The view will receive user input, potentially fetch data (which will be added to the store), run some filter function on the Redux state, and display the results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With