I have this question in my mind from past couple of days. What is the best way to capture data from an API in our redux store. I am using redux toolkit.
For e.g below is the code -
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {},
extraReducers: builder => {
builder
.addCase(authUser.pending, state => {
state.loading = 'pending';
})
.addCase(authUser.fulfilled, (state: LoginState, action: PayloadAction<Data>) => {
state.loading = 'succeeded';
state.entities.push(action.payload);
})
},
});
Like I have created an array, entities
and pushed all the data inside it. And if I have to access this data inside my react components, it looks like this -
const role = useSelector((state: RootState) => state?.user?.entities[0]?.roles[0])
Is it fine or is there a better way of doing it. ?
CodePudding user response:
Definitely, there is a better way of doing it. Your current approach is not scalable. Solution to your issue is create selector(*.selectors.ts
) files.
For your above code example, create selector file as:
user.selectors.ts
:
import { createSelector } from "@reduxjs/toolkit";
const selectAllUsers = (state) => state.entities;
const selectUserById = (userId) =>
createSelector(selectAllUsers, (state) =>
state.find((user) => user.id === userId)
);
To use the same in your component files:
const allUsers = useSelector(selectAllUsers); // all users
const selctedUser = useSelector(selectUserById(9)); // user by id
Hope that answers your question.
Some useful link:
Thanks
CodePudding user response:
All of this is covered in the official Redux Tutorial.
This specific question is covered in chapter 6 - you could do this with an entityAdapter
, which would give you helpers to manage that entities
collection and would also auto-create selectors for your.
But generally, I would recommend you read the whole thing - you are probably missing out on other features too if you ask this question.