-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
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
Exposing static methods on decorated components #181
Comments
There is also the possibility of having a little helper which loops over the decorated components until it finds the root and then calls the method on it: const callMethod = (Component, method, ...args) => {
while(Component.DecoratedComponent) {
Component = Component.DecoratedComponent;
}
return Component[method] && Component[method](...args);
}; Then you'd do: callMethod(AScreen, 'getTitle'); The above could be refined to support multiple methods, e.g. when you define a static method which the decorator defines too. It could then return an array of results. Copying would make your could just look like nothing changed, which is a good thing, but could - albeit an edge case - possibly overwrite a static method defined on the decorator. (Except when the copying algo is intelligent enough to check whether a method exists and then to wrap it and properly return both results. |
To be honest I don't think decorating libraries should solve this. |
@johanneslumpe @gaearon Yeah, there might not be a graceful solution. I'm not a big fan of the I'll mull over this some more since there might be another way to connect the component to redux... a mixin might work well here for example. |
Way late to the party here, but I'm currently experimenting with the following. It's probably super-evil, and I wouldn't expect it to be included in anything expected for general consumption, but its working for my purposes (ReactRouter's Note: I'm not currently worried about cross-browser support. If import {connect} from 'react-redux'
/**
* Wrap redux connect in order to maintain static properties.
*/
function connectWithStaticsDecorator (select, actions, merge) {
var reduxConnect = connect(select, actions, merge)
return function connectWithStatics (Component) {
let statics = {}
// Babel/ES6 makes static methods non-enumerable.
Object.getOwnPropertyNames(Component).forEach(function (name) {
if (typeof Component[name] === 'function') {
statics[name] = Component[name]
}
})
// Get all enumerable props.
Object.keys(Component).forEach(function (name) {
statics[name] = Component[name]
})
// Run the redux connect decorator.
let ConnectedComponent = reduxConnect(Component)
// Apply statics and return.
Object.keys(statics).forEach((key) => {
if (typeof ConnectedComponent[key] === 'undefined') {
ConnectedComponent[key] = statics[key]
}
})
return ConnectedComponent
}
}
export default connectWithStaticsDecorator |
I published a module called autoproxy if anyone's interested. It's a higher-order decorator and you use it like @autoproxy(connect(selector)). |
@ide Very cool, I'll give it a whirl. I should have known you'd solve your own problem and explored your github! |
I want to be able to take a component that has some static methods and decorate it with
@connect
without needing to change other code... so for example:and then I want to connect AScreen to Redux:
but now have to change all the callers to read
AScreen.DecoratedComponent.getTitle()
.This is a problem with decorators as much as it's a problem with Redux but it is a rough edge I encountered when using Redux in practice. The decorator could copy all static methods off of the decorated component and add them to the wrapper if you think that is pragmatic enough to be tasteful.
The text was updated successfully, but these errors were encountered: