-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add stateThunk / dispatchThunk options #179
Conversation
Can you please elaborate on usage? I don't quite understand this. |
It isn't necessarily specific to Reselect. The issue is that in order to properly memoize the This seemed like the best way to go about it, without exposing too much information about the component to the |
OK, I get the use case now. Can this be solved as a wrapper around |
A wrapper around |
@ellbee Appreciate you taking a look. Thanks. 💯 |
Yep, latest commit just adds an assignMapFunctions() {
this.finalMapStateToProps = finalMapStateToProps
this.finalMapDispatchToProps = finalMapDispatchToProps
} This eliminates the need for any additional options and allows the user to wrap this method on the component and wrap/re-assign the Let me know if this seems like a reasonable approach, and if so I can cleanup the commits. |
I don't understand your latest proposal yet and I'm busy with something else, so I trust @ellbee to make the right call on this. |
I have checked out the PR, and the approach looks reasonable but I am concerned that the I was also wondering if we can achieve the same thing without making any changes to import React from 'react'
import { connect } from 'react-redux'
export default function connectWrapper(
Component,
mapStateThunk,
mapDispatchThunk,
mergeProps,
options = {}
) {
const Wrapped = class extends React.Component {
constructor() {
super()
this.component = connect(
mapStateThunk(),
mapDispatchThunk(),
mergeProps,
options
)(Component)
}
render() {
return <this.component {...this.props} {...this.state} />
}
}
Wrapped.displayName = `WrappedConnect(${Component.displayName})`
return Wrapped
}; Advantages of the approach above: No changes to Advantages of the PR: Does not create a new wrapper class for each instantiation of the component @tgriesser What do you think? Is creating a new wrapper class every time going to be a problem? Have I missed anything? |
Creating a new class is definitely a big problem: React will bail out of reconciling such components. So you won't be able to handle |
Blurgh, yes of course, it is not even going to try if they are of different types. Ok, back to the drawing board. |
Yeah it's sort of a tough one... I don't think there's a way to achieve it without changing something about the connect implementation - it's really more of a matter of what's cleanest / least invasive. I've got another approach that might be a little better I'll open a separate PR for. |
Closing in favor of #180 |
So after thinking about it for a bit, I wouldn't mind if the answer were that this behavior is a non-goal for I could fork and create a |
I agree with you, I can't see a way to do this without making some changes to Just out of interest, is there a reason why using Reselect's |
I'm actually using |
Ah, ok. It is useful to know that
Interesting. Could you explain this point a bit more please? I'm not sure I follow why I would need to know what component I am checking props against.
This may be the best option if we can't find a slightly cleaner way to get this in. I'm not keen on encouraging the use of the private API. Even if we leave it undocumented, people might start using it if it can be found in the tests. |
Once you move beyond a single prop or combo of props it becomes ugly and quite expensive to need to serialize props to use as a cache key. It seems it'd be simpler if it could be more like react's Unless I'm missing something obvious (which I might be), I don't think it's something that can be resolved without changing the design of react-redux quite a bit. Unrelated, but I was curious what the reasoning for the undocumented |
From the point of view of Reselect, I was thinking about something along the lines of how Immutable-js allows objects to be a key in a Map (it basically tags the object with a non-enumerable id) to avoid serialization of large objects, combined with something like a LRU cache to avoid the cache size getting out of control. It may come to nothing, but I am going to give it a go. Yeah, |
Ah okay so that actually may work fine. I took another look at the code and I'm realizing what I'm actually after is a way to configure the shallowEqual comparison in react-redux similar to what is possible in reselect. Just opened #182 to discuss. |
FYI I closed #185 because I don’t plan to merge it as is but I’m happy to consider merging #185 (comment) which should solve the same problem if somebody gets to implementing it. |
This is implemented in #279 and shipped in 4.3.0. |
🎉 Nice work @tgriesser! |
Adds two new options,
stateThunk
anddispatchThunk
. When set to true, it signifies that the value ofmapStateToProps
ormapDispatchToProps
are thunks, called in the constructor & return values stored on the connected component class.The use case comes from reselect - I noticed that although functions are memoized, when using
props
it destroys the utility of the memoziation feature. The idea here is that each connected component would return a unique memoized selector, rather than sharing one between all instances of a component and ending up with a ton of cache misses.So instead of:
You'd do: