This is my code for cretaing Selectors
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'Store/InjectorsTypes';
import { initialState } from 'Slice/DocumentHubSlice';
const selectDomain = (state: RootState) => state?.documentHub || initialState;
export const selectDocuments = createSelector(
[selectDomain],
(state) => state.documents,
);
export const selectUploadedDocuments = createSelector(
[selectDomain],
(state) => state.uploadedDocuments,
);
export const selectDocumentsLoading = createSelector(
[selectDomain],
(state) => state.documentsLoading,
);
export const selectDocumentsLoaded = createSelector(
[selectDomain],
(state) => state.documentsLoaded,
);
export const selectDocumentsEnded = createSelector(
[selectDomain],
(state) => state.documentsEnded,
);
export const selectSort = createSelector(
[selectDomain],
(state) => state.sort,
);
export const selectCompanyName = createSelector(
[selectDomain],
(state) => state.companyName,
);
export const selectCompanyLogo = createSelector(
[selectDomain],
(state) => state.companyLogo,
);
export const selectChatGptAllowed = createSelector(
[selectDomain],
(state) => state.chatgptAllowed,
);
export const selectDrawerOpen = createSelector(
[selectDomain],
(state) => state.drawerOpen,
);
export const selectUploading = createSelector(
[selectDomain],
(state) => state.uploading,
);
export const selectDownloading = createSelector(
[selectDomain],
(state) => state.downloading,
);
export const selectDeleting = createSelector(
[selectDomain],
(state) => state.deleteing,
);
export const selectDownloadUrl = createSelector(
[selectDomain],
(state) => state.downloadUrl,
);
However, I can see too much redundancy. I want to replace above code with my this code
import { useSelector } from 'react-redux';
import { RootState } from 'Store/InjectorsTypes';
import { initialState } from 'Slice/DocumentHubSlice';
export function useAppSelector<T>(selector: (state: RootState) => T) {
return useSelector((state: RootState) => selector(state) || initialState);
}
With this custom hook, I can use it in my components like this
const documents = useAppSelector((state) => state.documentHub.documents);
const uploadedDocuments = useAppSelector((state) => state.documentHub.uploadedDocuments);
// ... and so on
I want to know if the second approach is better than the first. Should I replace my initial code with this second appraoch?
Generally, you should always be using the
useAppSelectorshown in the "TypeScript quickstart" guide for Redux Toolkit, independenlty of the question if you usecreateSelectoror not.Apart from that, you probably don't need
createSelectorfor any of the examples you've given, as long as those selectors don't do any meaningful (expensive) calculation or create new objects - in those two cases, you should always use memoized selectors.But it doesn't hurt to use them either - so it's up to you.
PS: That
|| initialStateis seriously weird - you'll always have a state there, so why add that?