From dab9b8b2fdaa13669a000e3aa37e1988113b8e15 Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Fri, 13 Apr 2018 13:23:19 -0300 Subject: [PATCH] Add 'visual components' use case for forwarding refs (#798) * Add 'visual components' use case for forwarding refs * Rearrange "forwarding refs" to focus on simple use case * Minor wording nits to 2018-03-29-react-v-16-3.md * Minor wording nits to forwarding-refs.md * Add more info to the forwardRef reference doc * Minor wording nits to reference-react.md --- content/blog/2018-03-29-react-v-16-3.md | 11 +++-- content/docs/forwarding-refs.md | 37 +++++++++++++++- content/docs/reference-react.md | 12 +++++- .../fancy-button-example.js | 42 +++++-------------- .../fancy-button-simple-ref.js | 10 +++++ .../forwarding-refs/fancy-button-simple.js | 7 ++++ examples/reference-react-forward-ref.js | 38 +++++------------ 7 files changed, 88 insertions(+), 69 deletions(-) create mode 100644 examples/forwarding-refs/fancy-button-simple-ref.js create mode 100644 examples/forwarding-refs/fancy-button-simple.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 70fdd3de..d758b59b 100644 --- a/content/blog/2018-03-29-react-v-16-3.md +++ b/content/blog/2018-03-29-react-v-16-3.md @@ -39,18 +39,17 @@ Version 16.3 adds a new option for managing refs that offers the convenience of ## `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: +Generally, React components are declarative, but sometimes imperative access to the component instances and the underlying DOM nodes is necessary. This is common for use cases like managing focus, selection, or animations. React provides [refs](/docs/refs-and-the-dom.html) as a way to solve this problem. However, component encapsulation poses some challenges with refs. -`embed:16-3-release-blog-post/hoc-theme-example.js` +For example, if you replace a ` - ); - } -} - -// 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. -; +// highlight-range{1-2} +const FancyButton = React.forwardRef((props, ref) => ( + +)); + +// You can now get a ref directly to the DOM button: +const ref = React.createRef(); +Click me!; diff --git a/examples/forwarding-refs/fancy-button-simple-ref.js b/examples/forwarding-refs/fancy-button-simple-ref.js new file mode 100644 index 00000000..f4d5f8e0 --- /dev/null +++ b/examples/forwarding-refs/fancy-button-simple-ref.js @@ -0,0 +1,10 @@ +// highlight-range{1-2} +const FancyButton = React.forwardRef((props, ref) => ( + +)); + +// You can now get a ref directly to the DOM button: +const ref = React.createRef(); +Click me!; diff --git a/examples/forwarding-refs/fancy-button-simple.js b/examples/forwarding-refs/fancy-button-simple.js new file mode 100644 index 00000000..d13ee1a7 --- /dev/null +++ b/examples/forwarding-refs/fancy-button-simple.js @@ -0,0 +1,7 @@ +function FancyButton(props) { + return ( + + ); +} diff --git a/examples/reference-react-forward-ref.js b/examples/reference-react-forward-ref.js index 92cfbecc..f4d5f8e0 100644 --- a/examples/reference-react-forward-ref.js +++ b/examples/reference-react-forward-ref.js @@ -1,28 +1,10 @@ -function enhance(Component) { - class Enhanced extends React.Component { - // ... - - render() { - const {forwardedRef, ...rest} = this.props; - - // Assign the custom prop "forwardedRef" as a ref - // highlight-next-line - return ; - } - } - - // Intercept the "ref" and pass it as a custom prop, e.g. "forwardedRef" - // highlight-range{1-3} - function enhanceForwardRef(props, ref) { - return ; - } - - // These next lines are not necessary, - // But they do give the component a better display name in DevTools, - // e.g. "ForwardRef(withTheme(MyComponent))" - const name = Component.displayName || Component.name; - enhanceForwardRef.displayName = `enhance(${name})`; - - // highlight-next-line - return React.forwardRef(enhanceForwardRef); -} +// highlight-range{1-2} +const FancyButton = React.forwardRef((props, ref) => ( + +)); + +// You can now get a ref directly to the DOM button: +const ref = React.createRef(); +Click me!;