From 691cd4577cdfaffb64caef2a39af6d4a1739799d Mon Sep 17 00:00:00 2001
From: Brian Vaughn <brian.david.vaughn@gmail.com>
Date: Thu, 29 Mar 2018 09:15:30 -0700
Subject: [PATCH] Added inline child function caveat to Context docs

---
 content/docs/context.md                           | 14 +++++++++++++-
 .../consumer-cached-function-as-a-child.js        | 15 +++++++++++++++
 .../consumer-inline-function-as-a-child.js        | 15 +++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 examples/context/consumer-cached-function-as-a-child.js
 create mode 100644 examples/context/consumer-inline-function-as-a-child.js

diff --git a/content/docs/context.md b/content/docs/context.md
index 2e54d512..d89f18fe 100644
--- a/content/docs/context.md
+++ b/content/docs/context.md
@@ -69,7 +69,9 @@ Accepts a `value` prop to be passed to Consumers that are descendants of this Pr
 
 A React component that subscribes to context changes.
 
-Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. All consumers are re-rendered whenever the Provider value changes. Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description). (This can cause some issues when passing objects as `value`: see [Caveats](#caveats).)
+Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. The function should be created inline, as shown in the example above, rather than being bound to the instance or otherwise cached. (Refer to the see [Caveats](#consumer-inline-function-as-a-child) section below for more.)
+
+All consumers are re-rendered whenever the Provider value changes. Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description). (This can cause some issues when passing objects as `value`: see [Caveats](#objectis).)
 
 > Note
 > 
@@ -134,6 +136,16 @@ One issue with the render prop API is that refs don't automatically get passed t
 
 ## Caveats
 
+### `Consumer` Inline Function as a Child
+
+As an optimization to avoid doing unnecessary work, React currently stops rendering when it sees children that are equal to the most recently rendered children. This applies to the [function as a child](/docs/render-props.html#using-props-other-than-render) pattern used by `Consumer` as well which can cause unexpected behavior in some situations:
+`embed:context/consumer-cached-function-as-a-child.js`
+
+To avoid this scenario, we recommend declaring the child function inline:
+`embed:context/consumer-inline-function-as-a-child.js`
+
+### `Object.is`
+
 Because context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider's parent re-renders. For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for `value`:
 
 `embed:context/reference-caveats-problem.js`
diff --git a/examples/context/consumer-cached-function-as-a-child.js b/examples/context/consumer-cached-function-as-a-child.js
new file mode 100644
index 00000000..b739e80b
--- /dev/null
+++ b/examples/context/consumer-cached-function-as-a-child.js
@@ -0,0 +1,15 @@
+class Example extends React.Component {
+  // This method will be called when the context value changes,
+  // But not when the props value changes!
+  renderValue = value => {
+    return (
+      <div>
+        Context value:{value}. Props value:{this.props.counter}
+      </div>
+    );
+  };
+
+  render() {
+    return <Ctx.Consumer>{this.renderValue}</Ctx.Consumer>;
+  }
+}
diff --git a/examples/context/consumer-inline-function-as-a-child.js b/examples/context/consumer-inline-function-as-a-child.js
new file mode 100644
index 00000000..3b75a54d
--- /dev/null
+++ b/examples/context/consumer-inline-function-as-a-child.js
@@ -0,0 +1,15 @@
+class Example extends React.Component {
+  render() {
+    // The inline function will be called when the context value changes,
+    // And when the props value changes!
+    return (
+      <Ctx.Consumer>
+        {value => (
+          <div>
+            Context value:{value}. Props value:{this.props.counter}
+          </div>
+        )}
+      </Ctx.Consumer>
+    );
+  }
+}