diff --git a/content/blog/2018-03-20-react-v-16-3.md b/content/blog/2018-03-20-react-v-16-3.md
index 8b336139..e6ed3a45 100644
--- a/content/blog/2018-03-20-react-v-16-3.md
+++ b/content/blog/2018-03-20-react-v-16-3.md
@@ -1,9 +1,9 @@
---
-title: "React v16.3.0: New lifecycles and context"
+title: "React v16.3.0: New lifecycles and context API"
author: [bvaughn]
---
-This release includes a new class component lifecycle (`getDerivedStateFromProps`), a new `StrictMode` component, an official context API, and a new ergonomic ref API!
+This release includes a new class component lifecycle (`getDerivedStateFromProps`), a new `StrictMode` component, an official context API, a new ergonomic ref API, and a ref-forwarding API!
For the past few months, the React team has been working on support for [asynchronous rendering](/blog/2018/03/01/sneak-peek-beyond-react-16.html). We are excited about the new features it will enable.
@@ -41,6 +41,21 @@ Version 16.3 adds a new option for managing refs that offers the convenience of
[Learn more about the new `createRef` API here.](/docs/refs-and-the-dom.html)
+## `forwardRef` API
+
+[Higher-order components](/docs/higher-order-components.html) (or HOCs) are a common way to reuse code between components. Building on the theme context example from above, we might create an HOC that injects the current "theme" as a prop:
+
+`embed:16-3-release-blog-post/hoc-theme-example.js`
+
+We can use the above HOC to wire components up to the theme context without having to use `ThemeContext` directly. For example:
+
+`embed:16-3-release-blog-post/fancy-button-example.js`
+
+HOCs typically [pass props through](/docs/higher-order-components.html#convention-pass-unrelated-props-through-to-the-wrapped-component) to the components they wrap. Unfortunately, [refs are not passed through](/docs/higher-order-components.html#refs-arent-passed-through). This means that we can't attach a ref to `FancyButton` if we use `FancyThemedButton`- so there's no way for us to call `focus()`.
+
+The new `forwardRef` API solves this problem by providing a way for us to intercept a `ref` and forward it as a normal prop:
+`embed:16-3-release-blog-post/forward-ref-example.js`
+
## Component Lifecycle Changes
React's class component API has been around for years with little change. However, as we add support for more advanced features (such as [error boundaries](/docs/react-component.html#componentdidcatch) and the upcoming [async rendering mode](/blog/2018/03/01/sneak-peek-beyond-react-16.html)) we stretch this model in ways that it was not originally intended.
diff --git a/examples/16-3-release-blog-post/create-ref-example.js b/examples/16-3-release-blog-post/create-ref-example.js
index 77cbb40a..7589fafa 100644
--- a/examples/16-3-release-blog-post/create-ref-example.js
+++ b/examples/16-3-release-blog-post/create-ref-example.js
@@ -9,6 +9,6 @@ class MyComponent extends React.Component {
componentDidMount() {
// highlight-next-line
- this.divRef.value.focus();
+ this.divRef.current.focus();
}
}
diff --git a/examples/16-3-release-blog-post/fancy-button-example.js b/examples/16-3-release-blog-post/fancy-button-example.js
new file mode 100644
index 00000000..22170e52
--- /dev/null
+++ b/examples/16-3-release-blog-post/fancy-button-example.js
@@ -0,0 +1,32 @@
+class FancyButton extends React.Component {
+ buttonRef = React.createRef();
+
+ focus() {
+ this.buttonRef.current.focus();
+ }
+
+ render() {
+ // highlight-next-line
+ const {label, theme, ...rest} = this.props;
+ // highlight-range{4}
+ return (
+
+ );
+ }
+}
+
+// highlight-next-line
+const FancyThemedButton = withTheme(FancyButton);
+
+// We can render FancyThemedButton as if it were a FancyButton
+// It will automatically receive the current "theme",
+// And the HOC will pass through our other props.
+;
diff --git a/examples/16-3-release-blog-post/forward-ref-example.js b/examples/16-3-release-blog-post/forward-ref-example.js
new file mode 100644
index 00000000..3c6193e0
--- /dev/null
+++ b/examples/16-3-release-blog-post/forward-ref-example.js
@@ -0,0 +1,34 @@
+function withTheme(Component) {
+ // highlight-next-line
+ function ThemedComponent({forwardedRef, ...rest}) {
+ // highlight-range{6}
+ return (
+
+ {theme => (
+
+ )}
+
+ );
+ }
+
+ // Intercept the "ref" and pass it as a custom prop.
+ // highlight-range{1-3}
+ return React.forwardRef((props, ref) => (
+
+ ));
+}
+
+// highlight-next-line
+const fancyButtonRef = React.createRef();
+
+// fancyButtonRef will now point to FancyButton
+// highlight-range{4}
+;
diff --git a/examples/16-3-release-blog-post/hoc-theme-example.js b/examples/16-3-release-blog-post/hoc-theme-example.js
new file mode 100644
index 00000000..ba0138de
--- /dev/null
+++ b/examples/16-3-release-blog-post/hoc-theme-example.js
@@ -0,0 +1,10 @@
+function withTheme(Component) {
+ return function ThemedComponent(props) {
+ // highlight-range{2-4}
+ return (
+
+ {theme => }
+
+ );
+ };
+}