0

In the example below, I'm seeing Child get unmounted and re-mounted on every ComponentA render. None of the other components in the tree are re-mounted.

class ComponentA extends Component {
  renderChild() {
    return <Child />;
  }
  render() {
    return <ComponentB>{this.renderChild()}</ComponentB>;
  }
}

class ComponentB extends Component {
  render() {
    return <ComponentC passthruChild={() => children} />;
  }
}

class ComponentC extends Component {
  render() {
    const PassedThruChild = this.props.passthruChild;
    return <div><PassedThruChild /></div>;
  }
}

Why is this happening, and how can I make it not happen?

Vikas Yadav
  • 3,094
  • 2
  • 20
  • 21
ericsoco
  • 24,913
  • 29
  • 97
  • 127
  • I've found that threading `Child` through as a JSX child rather than passing as a prop eliminates the problem, but the design of my application makes this solution unworkable as there are multiple child components passed into ComponentB; these are then passed down to different parts of the component tree below. – ericsoco Feb 07 '18 at 07:58
  • You could use the `componentShouldUpdate` lifecycle and return false programatically based on certain props that your children have? This should, in theory, only trigger a re-render when certain conditions are met. – bamtheboozle Feb 07 '18 at 08:08
  • @DragoşPaulMarinescu the issue is not a re-render, it's a re-mount. – ericsoco Feb 07 '18 at 08:08
  • Never figured out exactly why this was a problem, but I worked around the issue by consistently passing `Child` as a prop. Side note, I needed to mix in other props when ultimately mounting `Child` in `ComponentC`, so used `React.cloneElement` for this purpose. More here: https://stackoverflow.com/a/32371612/222356 – ericsoco Feb 08 '18 at 19:19

1 Answers1

1

This is entirely speculative but I think it could be something along the lines of: when ComponentA renders, a new instance of Child gets returned by this.renderChild(). This instance is different from some cached instance which results in the cached child being replaced with the new instance. Cached one being unmounted and the new one being mounted.

In the other two cases the pass thru child could be a reference to the same object across multiple renders.

I think you should be able to check and see if they are the same object or a different object using the dev tools.

I can't post a reply to your comment since I don't have 50 points so I will answer here:

If you save were to cache the returned object from this.renderChild() so that you're not creating a new one every time the function is called you could probably make it work.

the.alch3m1st
  • 56
  • 1
  • 5
  • Yeah, I think it's something along these lines but can't pinpoint it. I can't cache the result of `renderChild` because the props I pass to `` (not shown in my example) are subject to change. – ericsoco Feb 07 '18 at 08:10
  • Could you update the cached version when the props change? – the.alch3m1st Feb 07 '18 at 08:11