flummox icon indicating copy to clipboard operation
flummox copied to clipboard

How to access base component instance from higher-order component instance

Open christophercliff opened this issue 10 years ago • 14 comments

Is this possible?

christophercliff avatar Jun 02 '15 16:06 christophercliff

@christophercliff Not sure what you are asking here, can you elaborate a bit?

johanneslumpe avatar Jun 02 '15 18:06 johanneslumpe

var MyComponent = React.createClass()
var MyConnectedComponent = connectoToStores(MyComponent)
var myConnectedComponent = TestUtils.renderIntoDocument(React.createElement(MyConnectedComponent))

Given the above, is it possible to access, for example, refs on the myComponent instance. I ended up using TestUtils.findRenderedComponentWithType(myConnectedComponent, MyComponent), which is fine for my use case. Thought there might be a more direct approach.

christophercliff avatar Jun 02 '15 19:06 christophercliff

The HoC does not keep a ref to the wrapped child. Because of that you cannot access your wrapped component directly.

johanneslumpe avatar Jun 02 '15 19:06 johanneslumpe

I'm re-opening this because I think we should expose the wrapped component e.g. for testing purposes. I looked around a bit and I don't think there's an existing convention in the React community, but perhaps something as simple as MyConnectedComponent.WrappedComponent.

acdlite avatar Jun 02 '15 19:06 acdlite

I might have been a bit overzealous here. For testing purposes exposing the wrapped component might be a good idea. But that means that you will have to test your component without being wrapped. If I understand the question correctly the idea is to get a reference to the rendered component instance, in order to check stuff there or to call methods on it. Then we'd need to attach a ref to the wrapped component.

@christophercliff Did I understand you correctly?

johanneslumpe avatar Jun 02 '15 20:06 johanneslumpe

Just exposing the wrapped class is sufficient. Then as @christophercliff noted above, you can use findRenderedComponentWithType() to get a ref to an instance.

acdlite avatar Jun 02 '15 20:06 acdlite

Ok so we're just talking about a shorter way for testing here.

johanneslumpe avatar Jun 02 '15 20:06 johanneslumpe

@johanneslumpe Not just shorter — if you're using decorators, then it's actually necessary, because you don't have any reference to the inner component.

But that means that you will have to test your component without being wrapped

In most cases, that's exactly what you want. The advantage of using higher-order components is that the wrapped component doesn't care about the underlying Flux implementation — it just receives props. So in your tests, rather than creating mock Flux dependencies, you pass some props.

acdlite avatar Jun 02 '15 20:06 acdlite

@acdlite oh yeah, decorators. Ok sure, it's not hard to fix this :) Also: true about not wanting to mock all the stuff - silly me.

johanneslumpe avatar Jun 02 '15 20:06 johanneslumpe

Yeah this will be a one-liner, just need to decide on the right name for the property. InnerComponent? WrappedComponent? BaseComponent?

acdlite avatar Jun 02 '15 20:06 acdlite

Actually, if you have multiple HoCs on the same base component, you need to loop through them. I like this approach:

https://github.com/vslinko/hoc/blob/master/index.js#L18-L23

acdlite avatar Jun 02 '15 20:06 acdlite

I think WrappedComponent makes the most sense, as it perfectly describes what happened to the original Component. We could the either provide a helper to which the user has to pass the component - just like in the repo you posted. Or we could provide a convenience method getWrappedComponent() which works the same, but starts off with this.

johanneslumpe avatar Jun 02 '15 20:06 johanneslumpe

I say we go with WrappedComponent then link to that repo in the docs. No need to provide our own helper, IMO.

acdlite avatar Jun 02 '15 20:06 acdlite

No, not necessary. Linking to the repo is fine. We should just really make sure that stuff like this is made really clear in some kind of FAQ section or a separate testing section :)

johanneslumpe avatar Jun 02 '15 20:06 johanneslumpe