<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong></p>
<p dir="auto">bug.</p>
<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">In a component tree where legacy context and new context are co-exisiting, when components are placed on tree nodes under the legacy context provider and between new context provider and consumer, components are always rendered even if <code class="notranslate">shouldComponentUpdate()</code> returns false in a parent component.</p>
<p dir="auto"><strong>If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.</strong></p>
<p dir="auto"><a href="https://jsfiddle.net/fdrgz9c4/15/" rel="nofollow">https://jsfiddle.net/fdrgz9c4/15/</a></p>
<p dir="auto">The above is the minimal case I've created without other dependencies, but first I found this behaviour in my Redux application, which uses legacy style context to map the state in store.</p>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">Should not call <code class="notranslate">render()</code> when <code class="notranslate">shouldComponentUpdate()</code> returns false in parent components, as same as the other cases (it prevents rendering when it is located without legacy context or not between new context provider / consumer tree. See the above fiddle)</p>
<p dir="auto"><strong>Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?</strong></p>
<p dir="auto">React 16.5.2, maybe in older versions.<br>
No OS/browser dependencies I believe.</p>
<p dir="auto">This issue is going to start off mostly theoretical as I’m still working to make a minimal repro case.</p>
<p dir="auto">We have a scenario where one component is having <code class="notranslate">shouldComponentUpdate()</code> return false to bail out, but a child component is still having its <code class="notranslate">render</code> method called.</p>
<p dir="auto">Avoiding many details this is roughly what we have:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import React, { Component } from 'react';

class A extends Component {
  shouldComponentUpdate(nextProps) {
    const result = Boolean(nextProps.item);
    console.log('A#shouldComponentUpdate?', result);
    return result;
  }

  render() {
    console.log('A#render', this.props.item);
    return &lt;B item={this.props.item} /&gt;;
  }
}

class B extends Component {
  state = { seconds: 0 };
  componentDidMount() {
    this._interval = setInterval(
      () =&gt; this.setState({ seconds: this.state.seconds + 1 }),
      1000
    );
  }

  componentWillUnMount() {
    clearInterval(this._interval);
  }

  render() {
    console.log('B#render', this.props.item);
    return (
      &lt;div&gt;
        &lt;strong&gt;{this.props.item.name}&lt;/strong&gt;
        &lt;span&gt;{this.state.seconds} seconds&lt;/span&gt;
      &lt;/div&gt;
    );
  }
}

export default A;"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-v">React</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-v">Component</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'react'</span><span class="pl-kos">;</span>

<span class="pl-k">class</span> <span class="pl-v">A</span> <span class="pl-k">extends</span> <span class="pl-v">Component</span> <span class="pl-kos">{</span>
  <span class="pl-en">shouldComponentUpdate</span><span class="pl-kos">(</span><span class="pl-s1">nextProps</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-v">Boolean</span><span class="pl-kos">(</span><span class="pl-s1">nextProps</span><span class="pl-kos">.</span><span class="pl-c1">item</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A#shouldComponentUpdate?'</span><span class="pl-kos">,</span> <span class="pl-s1">result</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">return</span> <span class="pl-s1">result</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A#render'</span><span class="pl-kos">,</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">item</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">return</span> <span class="pl-c1">&lt;</span><span class="pl-ent">B</span> <span class="pl-c1">item</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">item</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-v">B</span> <span class="pl-k">extends</span> <span class="pl-v">Component</span> <span class="pl-kos">{</span>
  <span class="pl-c1">state</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">seconds</span>: <span class="pl-c1">0</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-en">componentDidMount</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_interval</span> <span class="pl-c1">=</span> <span class="pl-en">setInterval</span><span class="pl-kos">(</span>
      <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">setState</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">seconds</span>: <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span><span class="pl-kos">.</span><span class="pl-c1">seconds</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-c1">1000</span>
    <span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">componentWillUnMount</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-en">clearInterval</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_interval</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'B#render'</span><span class="pl-kos">,</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">item</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">return</span> <span class="pl-kos">(</span>
      <span class="pl-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
        <span class="pl-c1">&lt;</span><span class="pl-ent">strong</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">item</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">strong</span><span class="pl-c1">&gt;</span>
        <span class="pl-c1">&lt;</span><span class="pl-ent">span</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span><span class="pl-kos">.</span><span class="pl-c1">seconds</span><span class="pl-kos">}</span> seconds<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">span</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
    <span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-v">A</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">While this case does work as expected it seems to be in the direction of the<br>
errors we’re seeing.</p>
<p dir="auto">There is something taking place in our render cycle where B is being rendered<br>
<em>without</em> reusing the <code class="notranslate">item</code> prop from the previous reconcile.</p>
<p dir="auto">My first question is are there any theories on why this may be happening that I<br>
can explore? We <em>are</em> using <code class="notranslate">context</code> as the parent of <code class="notranslate">A</code> and as<code class="notranslate">B</code> and these<br>
are reading from a <code class="notranslate">flux</code>-thing (I think a fork of the original OSS Flux), they<br>
they these are both passing all props through and not having any naming<br>
collisions. I’m fairly certain we are not performing any mutations on our end.</p>
<p dir="auto">(If I do manage to pull off a repro case I will immediately post it here with<br>
utter joy in my heart)</p>
<p dir="auto">cc <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/acdlite/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/acdlite">@acdlite</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/gaearon/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/gaearon">@gaearon</a> (this is the issue I was asking about in Messenger recently)</p>