From f450adbdec1f1004d644c2967d742143f8193d8c Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 4 Apr 2018 23:39:00 +0900 Subject: [PATCH] Add a section "Displaying a custom name in DevTools" --- content/blog/2018-03-29-react-v-16-3.md | 2 ++ content/docs/forwarding-refs.md | 15 +++++++++++++++ .../forwarding-refs/customized-display-name.js | 17 +++++++++++++++++ examples/forwarding-refs/log-props-after.js | 13 ++----------- .../wrapped-component-with-function-name.js | 5 +++++ examples/forwarding-refs/wrapped-component.js | 3 +++ 6 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 examples/forwarding-refs/customized-display-name.js create mode 100644 examples/forwarding-refs/wrapped-component-with-function-name.js create mode 100644 examples/forwarding-refs/wrapped-component.js diff --git a/content/blog/2018-03-29-react-v-16-3.md b/content/blog/2018-03-29-react-v-16-3.md index 7f741cd4..70fdd3de 100644 --- a/content/blog/2018-03-29-react-v-16-3.md +++ b/content/blog/2018-03-29-react-v-16-3.md @@ -52,6 +52,8 @@ HOCs typically [pass props through](/docs/higher-order-components.html#conventio 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` +[Learn more about the forwardRef API here.](/docs/forwarding-refs.html) + ## 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/content/docs/forwarding-refs.md b/content/docs/forwarding-refs.md index dcebdbfa..5e535147 100644 --- a/content/docs/forwarding-refs.md +++ b/content/docs/forwarding-refs.md @@ -20,3 +20,18 @@ This means that refs intended for our `FancyButton` component will actually be a Fortunately, we can explicitly forward refs to the inner `FancyButton` component using the `React.forwardRef` API. `React.forwardRef` accepts a render function that receives `props` and `ref` parameters and returns a React node. For example: `embed:forwarding-refs/log-props-after.js` +## Displaying a custom name in DevTools + +`React.forwardRef` accepts a render function. React DevTools uses this function to determine what to display for the ref forwarding component. + +For example, the following component will appear as "*ForwardRef*" in the DevTools: + +`embed:forwarding-refs/wrapped-component.js` + +If you name the render function, DevTools will include its name (e.g. "*ForwardRef(myFunction)*"): + +`embed:forwarding-refs/wrapped-component-with-function-name.js` + +You can even set the function's `displayName` property to include the component you're wrapping: + +`embed:forwarding-refs/customized-display-name.js` diff --git a/examples/forwarding-refs/customized-display-name.js b/examples/forwarding-refs/customized-display-name.js new file mode 100644 index 00000000..28bbd920 --- /dev/null +++ b/examples/forwarding-refs/customized-display-name.js @@ -0,0 +1,17 @@ +function logProps(Component) { + class LogProps extends React.Component { + // ... + } + + function forwardRef(props, ref) { + return ; + } + + // Give this component a more helpful display name in DevTools. + // e.g. "ForwardRef(logProps(MyComponent))" + // highlight-range{1-2} + const name = Component.displayName || Component.name; + forwardRef.displayName = `logProps(${name})`; + + return React.forwardRef(forwardRef); +} diff --git a/examples/forwarding-refs/log-props-after.js b/examples/forwarding-refs/log-props-after.js index 0c33e8a2..a603bd69 100644 --- a/examples/forwarding-refs/log-props-after.js +++ b/examples/forwarding-refs/log-props-after.js @@ -19,16 +19,7 @@ function logProps(Component) { // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef" // And it can then be attached to the Component. // highlight-range{1-3} - function forwardRef(props, ref) { + return React.forwardRef((props, ref) => { return ; - } - - // These next lines are not necessary, - // But they do give the component a better display name in DevTools, - // e.g. "ForwardRef(logProps(MyComponent))" - // highlight-range{1-2} - const name = Component.displayName || Component.name; - forwardRef.displayName = `logProps(${name})`; - - return React.forwardRef(forwardRef); + }); } diff --git a/examples/forwarding-refs/wrapped-component-with-function-name.js b/examples/forwarding-refs/wrapped-component-with-function-name.js new file mode 100644 index 00000000..f68b5c5d --- /dev/null +++ b/examples/forwarding-refs/wrapped-component-with-function-name.js @@ -0,0 +1,5 @@ +const WrappedComponent = React.forwardRef( + function myFunction(props, ref) { + return ; + } +); diff --git a/examples/forwarding-refs/wrapped-component.js b/examples/forwarding-refs/wrapped-component.js new file mode 100644 index 00000000..f20e7f59 --- /dev/null +++ b/examples/forwarding-refs/wrapped-component.js @@ -0,0 +1,3 @@ +const WrappedComponent = React.forwardRef((props, ref) => { + return ; +});