5

My app structure is as follows (HighOrderComponent is Alt's AltContainer wrapper):

<App>
    <HighOrderComponent store={someStore...}>
        <MyCanvasComponent ref="canvasRef" />
    </HighOrderComponent>
</App>

I need to expose a collectData() method from the MyCanvasComponent since the canvas needs to transform its content to a base64 image once a button is clicked in the App component.

I would like, in the button's click handler, to be able to use this.refs.canvasRef.collectData().

Unfortunately, it seems that nested components refs are not being taken into account. I know that generally refs should be considered private (i.e. belong to the HighOrderComponent) but -

  1. They are not available on it as well, meaning if I assign a ref="highOrderComponentRef" then this.refs.highOrderComponentRef would work but this.refs.highOrderComponentRef.refs.canvasRef wouldn't.

  2. The HighOrderComponent is a generic component and therefore does not know what its children would be.

The this.props.children on the HighOrderComponent are of ReactElement type which is lightweight and does not expose their methods.

The only solution so far is to pass the MyCanvasComponent a callback in which it will send itself and a reference will be saved, but this is tedious and against best practices as per React 0.13 release notes

ref resolution order has changed slightly such that a ref to a component is available immediately after its componentDidMount method is called; this change should be observable only if your component calls a parent component's callback within your componentDidMount, which is an anti-pattern and should be avoided regardless

Bart Riordan
  • 436
  • 3
  • 8
  • 23
Shahar
  • 478
  • 5
  • 17
  • 2
    Why do need to call the `collectData()` method on the ref (which is the mounted DOM component)? Alternative (and more in line with react): define a state `collectData: false` in The component, pass this to the canvas component ``. Inside the canvascomponent (probably inside getInitialData + inside componentWillUpdate), do `if (this.props.collectData) {collectData();}`. When user clicks button (part of top component), this fires a `this.setState({collectData: true})` – wintvelt Oct 08 '15 at 13:43
  • @wintvelt willl try this. thanks – Shahar Oct 08 '15 at 15:21
  • Ran into this same issue :( Unfortunately both the higher order component and the child are packages, therefore I don't feel entirely comfortable modifying them... – Ruben Martinez Jr. Jun 06 '16 at 18:34
  • Possible duplicate of [list not ordering well dynamic children](http://stackoverflow.com/questions/30821993/list-not-ordering-well-dynamic-children) – Paul Sweatte Jan 18 '17 at 03:03

0 Answers0