I am using react-redux for my react project, apparently, there are 2 ways to use the redux state
connect
or useSelector
,
My redux store has a reducer for each page,
For Home Page > homePageReducer
For Message Page > messagePageReducer
For Authentication > authReducer
For User’s blog > blogReducer
For Settings > userSettingsReducer
For User’s Profile > userProfileReducer
In my top-level component or the main component, I have used a selector hook to get all the reducer and passed down the reducers as props to the required components
const {home, messages, auth, settings, blogs} = useSelector( (state:RootState) => state) return( <main> <Switch> <Route exact to={HOME_ROUTE}> <HomeApp auth={auth} settings={settings} userProfile={userProfile}/> </Route> <Route exact to={CHAT_ROUTE}> <ChatApp auth={auth} messages={messages} userProfile={userProfile}/> </Route> <Route exact to={BLOG_ROUTE}> <BlogApp auth={auth} blogs={blogs} userProfile={userProfile}/> </Route> </Switch> </main> )
Is it a good architecture for my project and bring no performance issue for my project or should I use connect
or useSelector hook
inside those components?
What is better?
Advertisement
Answer
Redux has a very useful Style Guide explaining all of the current best practices. There are a few recommendations on that list that are applicable to your example.
Use the React-Redux Hooks API
Prefer using the React-Redux hooks API (
useSelector
anduseDispatch
) as the default way to interact with a Redux store from your React components.
Connect More Components to Read Data from the Store
Prefer having more UI components subscribed to the Redux store and reading data at a more granular level. This typically leads to better UI performance, as fewer components will need to render when a given piece of state changes.
Call useSelector Multiple Times in Function Components
When retrieving data using the
useSelector
hook, prefer callinguseSelector
many times and retrieving smaller amounts of data, instead of having a single largeruseSelector
call that returns multiple results in an object.
You definitely want to use useSelector
. Rather than selecting everything in the parent and passing it down, your Route
render components should take no props and get everything that they need from Redux themselves.
const App = { return( <Switch> <Route exact to={HOME_ROUTE}> <HomeApp /> </Route> <Route exact to={CHAT_ROUTE}> <ChatApp /> </Route> <Route exact to={BLOG_ROUTE}> <BlogApp /> </Route> </Switch> ) }
const HomeApp = () => { const userProfile = useSelector( (state: RootState) => state.user ); // We probably don't need the whole auth object const isLoggedIn = useSelector( (state: RootState) => !! state.auth ); // Do you need to return *every* setting? Just select what you need. const settings = useSelector( (state: RootState) => state.settings ); ... }
You might want to create selector functions especially for commonly-accessed values like userProfile
.
An alternative to modifying the current components HomeApp
etc. would be to create a HomeScreen
component as a wrapper around HomeApp
and keep HomeApp
as a pure presentational component. HomeScreen
would get all of the data from Redux and call HomeApp
with the correct props.