Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't React cache html elements of child components?

Hiello!

I'm wondering whats wrong in the React example bellow or if React works differently than I thought?

I'm looking for a way to reuse the underlying html element for a child react component, when the parents are two different components.

In the example bellow, I would like the inside the Circle component to have the same element after renderC1 and renderC2 is called. For instance so that I could apply a transition css property to animate the color switch, like they would if I e.g. just changed the style directly on the element.

When I render the bellow, React always seems to generate different HTML elements, ref, key or id on the DIV (in the render function of Circle) doesn't help much.

So my questions: is it possible to get React to just reuse the DIV that gets rendered via C1 when C2 is rendered? I thought this was how React should work, optimizing the underlying HTML elements?

Something like:

var C1 = React.createClass({
  render: function () {
    return (
        <Circle background="deeppink" onClick={renderC2}/>
     );
  }
});

function renderC1 () {
  React.render(
    <C1 />, 
    document.getElementById('mount-point'));
}

var C2 = React.createClass({
  render: function () {
    return (
        <Circle background="salmon" onClick={renderC1}/>
     );
  }
});

function renderC2 () {
      React.render(
    <C2 />, 
    document.getElementById('mount-point'));
}

var Circle = React.createClass({
  styler: {
    width: "100px",
    height: "100px",
    mozBorderRadius: "50%",
    webkitBorderRadius: "50%",
    borderRadius: "50%",
    background: 'hotpink'
  },

  componentWillMount: function() {
    if (this.props && this.props.background &&
       this.props.background !== this.styler.background) {
         this.styler.background = this.props.background;
    }
  },

  render: function() {
    return (
      {/* tried adding key, ref and id, but does not reuse element */}
      <div onClick={this.props.onClick} style={this.styler}></div>
    );
  }
});

renderC1();
like image 460
js4ftw Avatar asked Mar 22 '26 06:03

js4ftw


1 Answers

This is impossible. The DOM does not allow one element to be in two places at once. Attempting to put a DOM element in a new location will automatically remove it from the old location.

You can see that here. (or more visually, here)

var parent1 = document.createElement('div'),
    parent2 = document.createElement('div'),
    child = document.createElement('div'),
    results = document.createElement('span');

  document.body.appendChild(results);
        
  parent1.appendChild(child);
  results.textContent += child.parentNode === parent1; //true
  parent2.appendChild(child);
  results.textContent += ', ' + (child.parentNode === parent1); //false
like image 152
Kyeotic Avatar answered Mar 23 '26 19:03

Kyeotic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!