Replies: 2 comments 6 replies
-
Hmm. So I definitely understand the "don't want to unnecessarily select data and cause re-renders" problem you're describing. However, there's two other options here that also work around the issue of needing access to the state at the time of a click without re-rendering, and neither of them requires the actual The first is to move this logic out into a thunk: const someThunk = (argFromComponent) => {
return (dispatch, getState) => {
// do whatever logic is necessary here
}
}
// then, in a component
const handleClick = () => {
dispatch(someThunk(someComponentStateValue))
} That way the logic that actually relies on the Redux state can access The other option is an amusing but technically valid abuse of thunks: const selectSomeStateThunk = (anySelectorFunctionHere) => {
return (dispatch, getState) => anySelectorFunctionHere(getState())
}
// then, in a component
const handleClick = () => {
const theSelectedState = dispatch(selectSomeStateThunk(selectSomeData))
// do more logic with the selected value
} This works because the thunk middleware causes
Now, I'll agree that But, I would still recommend trying to avoid directly referencing the store in a component if needed, and in this case I'd prefer one of the thunk-based options instead of |
Beta Was this translation helpful? Give feedback.
-
Is there a technical reason why this should be avoided? |
Beta Was this translation helpful? Give feedback.
-
The
useStore
docs say:I wanted to address why I think this should be re-worded and discuss something I don't hear/see much talked about in the Redux community of why
useStore
is so valuable.We have a pretty complicated (feature and performance-wise) application with thousands of components on a page, heavy virtualization, with drag and drop. We have had to do extensive work on ensuring we don't have extra re-renders in our components (and thus, especially in our shared hooks) because the effects could be very large.
One of our key techniques to preventing unnecessary re-renders with regards to data from our Redux store has been accessing the Redux state on the fly when we don't need that data bound to the ui. In smaller scale apps, binding the data to the ui (aka
useSelector
) works just fine. But as the app grows, this can grow into a real re-render issue. Let me show a basic example.Bad for performance
The problem here is that if
val
changes in Redux, this component will re-render. Now, it's just a button that will be re-rendered, so it's not a big deal. But if this selector was being used in a shared hook (and who's not writing reusable hooks with lots of shared logic these days?) this has the potential to cause lots of unnecessary re-renders.We asks ourselves this: if the UI isn't visually changing, we probably don't need to cause a re-render. React is, at its core, a view library.
In the above example,
val
isn't used in the UI - just in the callback. Updating the callback just becauseval
updated isn't necessary. Instead we can go get the value ofval
on the fly when the user clicks. Like so:Better for performance
I'm calling this out because although
useSelector
is the obvious choice when you want to bind your data to the view, I'd argueuseStore
is the one you'd want to use when you don't. And I think there are a lot of use cases in a traditional app and something most developers should be aware of.Beta Was this translation helpful? Give feedback.
All reactions