Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
Have @connect hoist statics (#99)
Browse files Browse the repository at this point in the history
* Have @connect hoist statics

Currently, `react-apollo`'s `@connect` strips any custom statics from the components it wraps; this'll preserve them, using the [same method employed by `react-redux`](https://github.com/reactjs/react-redux/blob/master/src/components/connect.js#L365)

* Test statics
  • Loading branch information
nevir authored and James Baxley committed Jul 8, 2016
1 parent 1254af8 commit 311ef4f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
16 changes: 16 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ declare module 'lodash.isequal' {
import main = require('~lodash/index');
export = main.isEqual;
}

declare module 'hoist-non-react-statics' {
interface Component {
new(...args:any[]);
}

/**
* Copies any static properties present on `source` to `target`, excluding those that are specific
* to React.
*
* Returns the target component.
*/
function hoistNonReactStatics(targetComponent:Component, sourceComponent:Component):Component;
namespace hoistNonReactStatics {}
export = hoistNonReactStatics;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"uglify-js": "^2.6.2"
},
"dependencies": {
"hoist-non-react-statics": "^1.2.0",
"invariant": "^2.2.1",
"lodash.isequal": "^4.1.1",
"lodash.isobject": "^3.0.2",
Expand Down
7 changes: 6 additions & 1 deletion src/connect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import isObject = require('lodash.isobject');
import isEqual = require('lodash.isequal');
import invariant = require('invariant');
import assign = require('object-assign');
import hoistNonReactStatics = require('hoist-non-react-statics');

import {
IMapStateToProps,
Expand Down Expand Up @@ -104,7 +105,8 @@ export default function connect(opts?: ConnectOptions) {
const version = nextVersion++;

return function wrapWithApolloComponent(WrappedComponent) {
const apolloConnectDisplayName = `Apollo(Connect(${getDisplayName(WrappedComponent)}))`;
// react-redux will wrap this further with Connect(...).
const apolloConnectDisplayName = `Apollo(${getDisplayName(WrappedComponent)})`;

class ApolloConnect extends Component<any, any> {
static displayName = apolloConnectDisplayName;
Expand Down Expand Up @@ -559,6 +561,9 @@ export default function connect(opts?: ConnectOptions) {

}

// Make sure we preserve any custom statics on the original component.
hoistNonReactStatics(ApolloConnect, WrappedComponent);

// apply react-redux args from original args
const { mapStateToProps, mapDispatchToProps, mergeProps, options } = opts;
return ReactReduxConnect(
Expand Down
34 changes: 34 additions & 0 deletions test/client/connect/statics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import * as React from 'react';
import * as chai from 'chai';

const { expect } = chai;

import connect from '../../../src/connect';

describe('statics', () => {
it('should be preserved', () => {
@connect({})
class ApolloContainer extends React.Component<any, any> {
static veryStatic = 'such global';
};

expect(ApolloContainer.veryStatic).to.eq('such global');
});

it('exposes a debuggable displayName', () => {
@connect({})
class ApolloContainer extends React.Component<any, any> {}

expect((ApolloContainer as any).displayName).to.eq('Connect(Apollo(ApolloContainer))');
});

it('honors custom display names', () => {
@connect({})
class ApolloContainer extends React.Component<any, any> {
static displayName = 'Foo';
}

expect((ApolloContainer as any).displayName).to.eq('Connect(Apollo(Foo))');
});
});

0 comments on commit 311ef4f

Please sign in to comment.