Okay, you’ve been probably using useSelector
hook wrong. TLDR; don’t use destructuring with useSelector
hook. Interested to know more? Let’s say that in your store you have a user object that looks like this.
export const state = { user: { id: 1, email: 'foo@bar.baz', name: 'Foo', plan: 'standard', photo: 'http://foobar.baz/user-1.jpg', // other properties }, }
Now, let’s say you have a React component that renders a user’s name and photo. We will use useSelector
hook to get the name and photo.
import React from 'react' import { useSelector } from 'react-redux' export const UserInfo = () => { const { name, photo } = useSelector(state => state.user) return ( <div> <img src={photo} /> <span>{name}</span> </div> ); }
The problem with useSelector hook
At first, this looks fine and everything works as expected but there’s one big downside. Destructuring and useSelector hook don’t play nice together. This component will re-render every time name and photo properties are changed. But it will also re-render if any other user object property gets changed. This could be a huge performance hit depending on how complex your app is.
Don’t use destructuring and useSelector hook at the same time
The solution is to refactor component to avoid destructuring like this.
import React from 'react' import { useSelector } from 'react-redux' export const UserInfo = () => { const name = useSelector(state => state.user.name) const photo = useSelector(state => state.user.photo) return ( <div> <img src={photo} /> <span>{name}</span> </div> ); }
One could argue that this is worse and involves more code repetition, especially if you need to pull a lot of data. In that case, you’re probably better off using connect and mapStateToProps.
What about?
const [name, photo] = useSelector(state => [state.user.name, state.user.photo])
Hi, Redux maintainer here. Thanks for the article, but please remove that “conclusion”. `connect` and `mapStateToProps` are at this point in time in `react-redux` for one single reason: to support legacy class components. You should not use them in any modern React code, ever.