I'm using Redux-tookit's createSlice and createEntityAdapter with normalized data.
This is a typical blog app with (posts, comments, users) - Entities
Usually, before using createEntityAdapter I would:
- Fetch, normalize and store data in
postsSlice
So my postSlicestatewould look something like this:
blogPosts: {entities: {posts: {}, users:{}, comments: {}}, ids:[]} - Get
id's frompostsSlice's state toPostscomponent - Pass comment/user
id's fromPostsdown to children -CommentUsercomponents, where they would get data using passedid's with selectors connected to parent'spostSlicestate
const postsAdapter = createEntityAdapter();
const postsSlice = createSlice({
name: "posts",
initialState: postsAdapter.getInitialState(),
reducers: {
setPosts: (state, { payload }) =>
postsAdapter.setAll(state, payload.entities.posts),
},
});
The problem is:
- When using
createEntityAdapter
Since we're usingcreateEntityAdapter.getInitialState()we get the same initialState{entities: {} ids: []}pattern in every slice. - And this doesn't allow to have initialState like I had before:
blogPosts: {entities: {posts: {}, users:{}, comments: {}}, ids:[]}
Should every component (Posts, User, Comment) have it's own slice/reducer and fetch it's own piece of data with thunk from the same endpoint?
So that: (according the createEntityAdapter.getInitialState() pattern)
postSlicestate would just contain post Entity -entities: {posts: {}, ids:[]}commentSlicestate - comments Entity -entities: {comments: {}, ids:[]}- etc...
No. There has never been a 1:1 association between components and Redux state structure. Instead, you should organize your state in terms of your data types and update logic, and components should access and re-shape that data for their own needs as necessary.
Note that there are multiple ways to approach structuring that data in the store even if it's being normalized. For example, you could have each data type as its own top-level slice, or have a shared
entitiesreducer with each of those types nested inside.