From b637cb31933dccf0facbe49d5373ffb0d6aaff59 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Tue, 6 Oct 2015 17:53:38 -0700 Subject: [PATCH] Updat docs for refs/findDOMNode --- docs/08-working-with-the-browser.md | 5 ++--- docs/08.1-more-about-refs.md | 18 +++++++++--------- docs/10.4-test-utils.md | 6 ++++-- docs/ref-01-top-level-api.md | 9 +++++---- docs/ref-03-component-specs.md | 2 +- docs/tutorial.md | 2 +- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/08-working-with-the-browser.md b/docs/08-working-with-the-browser.md index aec2aaa2..4e2c7ff9 100644 --- a/docs/08-working-with-the-browser.md +++ b/docs/08-working-with-the-browser.md @@ -56,10 +56,9 @@ React provides lifecycle methods that you can specify to hook into this process. ### Mounted Methods -_Mounted_ composite components also support the following methods: +_Mounted_ composite components also support the following method: -* `findDOMNode(): DOMElement` can be invoked on any mounted component in order to obtain a reference to its rendered DOM node. -* `forceUpdate()` can be invoked on any mounted component when you know that some deeper aspect of the component's state has changed without using `this.setState()`. +* `component.forceUpdate()` can be invoked on any mounted component when you know that some deeper aspect of the component's state has changed without using `this.setState()`. ## Browser Support and Polyfills diff --git a/docs/08.1-more-about-refs.md b/docs/08.1-more-about-refs.md index 8eefaab1..f1ae11f9 100644 --- a/docs/08.1-more-about-refs.md +++ b/docs/08.1-more-about-refs.md @@ -63,9 +63,9 @@ or using an ES6 arrow function: }, ``` -Note that when the referenced component is unmounted and whenever the ref changes, the old ref will be called with `null` as an argument. This prevents memory leaks in the case that the instance is stored, as in the first example. Also note that when writing refs with inline function expressions as in the examples here, React sees a different function object each time so on every update, ref will be called with `null` immediately before it's called with the component instance. +When attaching a ref to a DOM component like `
`, you get the DOM node back; when attaching a ref to a composite component like ``, you'll get the React class instance. In the latter case, you can call methods on that component if any are exposed in its class definition. -You can access the component's DOM node directly by calling `ReactDOM.findDOMNode(argumentToYourCallback)`. +Note that when the referenced component is unmounted and whenever the ref changes, the old ref will be called with `null` as an argument. This prevents memory leaks in the case that the instance is stored, as in the first example. Also note that when writing refs with inline function expressions as in the examples here, React sees a different function object each time so on every update, ref will be called with `null` immediately before it's called with the component instance. ## The ref String Attribute @@ -81,11 +81,11 @@ React also supports using a string (instead of a callback) as a ref prop on any 2. In some other code (typically event handler code), access the **backing instance** via `this.refs` as in: ```javascript - this.refs.myInput + var input = this.refs.myInput; + var inputValue = input.value; + var inputRect = input.getBoundingClientRect(); ``` - You can access the component's DOM node directly by calling `ReactDOM.findDOMNode(this.refs.myInput)`. - ## A Complete Example In order to get a reference to a React component, you can either use `this` to get the current React component, or you can use a ref to get a reference to a component you own. They work like this: @@ -120,7 +120,7 @@ ReactDOM.render( In this example, we get a reference to the text input **backing instance** and we call `focus()` when the button is clicked. -For composite components, the reference will refer to an instance of the component class so you can invoke any methods that are defined on that class. If you need access to the underlying DOM node for that component, you can use [ReactDOM.findDOMNode](/react/docs/top-level-api.html#reactdom.finddomnode). +For composite components, the reference will refer to an instance of the component class so you can invoke any methods that are defined on that class. If you need access to the underlying DOM node for that component, you can use [ReactDOM.findDOMNode](/react/docs/top-level-api.html#reactdom.finddomnode) as an "escape hatch" but we don't recommend it since it breaks encapsulation and in almost every case there's a clearer way to structure your code within the React model. ## Summary @@ -128,13 +128,13 @@ Refs are a great way to send a message to a particular child instance in a way t ### Benefits: -- You can define any public method on your component classes (such as a reset method on a Typeahead) and call those public methods through refs (such as `this.refs.myTypeahead.reset()`). -- Performing DOM measurements almost always requires reaching out to a "native" component such as `` and accessing its underlying DOM node via `ReactDOM.findDOMNode(this.refs.myInput)`. Refs are one of the only practical ways of doing this reliably. +- You can define any public method on your component classes (such as a reset method on a Typeahead) and call those public methods through refs (such as `this.refs.myTypeahead.reset()`). In most cases, it's clearer to use the built-in React data flow instead of using refs imperatively. +- Performing DOM measurements almost always requires reaching out to a "native" component such as `` and accessing its underlying DOM node using a ref. Refs are one of the only practical ways of doing this reliably. - Refs are automatically managed for you! If that child is destroyed, its ref is also destroyed for you. No worrying about memory here (unless you do something crazy to retain a reference yourself). ### Cautions: - *Never* access refs inside of any component's render method - or while any component's render method is even running anywhere in the call stack. -- If you want to preserve Google Closure Compiler Crushing resilience, make sure to never access as a property what was specified as a string. This means you must access using `this.refs['myRefString']` if your ref was defined as `ref="myRefString"`. +- If you want to preserve Google Closure Compiler advanced-mode crushing resilience, make sure to never access as a property what was specified as a string. This means you must access using `this.refs['myRefString']` if your ref was defined as `ref="myRefString"`. - If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where `state` should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use `ref`s to "make things happen" – instead, the data flow will usually accomplish your goal. - Refs may not be attached to a [stateless function](/react/docs/reusable-components.html#stateless-functions), because the component does not have a backing instance. You can always wrap a stateless component in a standard composite component and attach a ref to the composite component. diff --git a/docs/10.4-test-utils.md b/docs/10.4-test-utils.md index 6edbabb6..28bdf5a7 100644 --- a/docs/10.4-test-utils.md +++ b/docs/10.4-test-utils.md @@ -26,14 +26,16 @@ Simulate an event dispatch on a DOM node with optional `eventData` event data. * **Clicking an element** ```javascript -var node = ReactDOM.findDOMNode(this.refs.button); +// +var node = this.refs.button; ReactTestUtils.Simulate.click(node); ``` **Changing the value of an input field and then pressing ENTER** ```javascript -var node = ReactDOM.findDOMNode(this.refs.input); +// +var node = this.refs.input; node.value = 'giraffe' ReactTestUtils.Simulate.change(node); ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13}); diff --git a/docs/ref-01-top-level-api.md b/docs/ref-01-top-level-api.md index 81676fd6..948c3196 100644 --- a/docs/ref-01-top-level-api.md +++ b/docs/ref-01-top-level-api.md @@ -128,7 +128,7 @@ Return the only child in `children`. Throws otherwise. ## ReactDOM -The `react-dom` package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside of the React model if you need to. +The `react-dom` package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside of the React model if you need to. Most of your components should not need to use this module. ### ReactDOM.render @@ -171,14 +171,15 @@ Remove a mounted React component from the DOM and clean up its event handlers an ```javascript DOMElement findDOMNode(ReactComponent component) ``` -If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements. When `render` returns `null` or `false`, `findDOMNode` returns `null`. +If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements. **In most cases, you can attach a ref to the DOM node and avoid using `findDOMNode` at all.** When `render` returns `null` or `false`, `findDOMNode` returns `null`. > Note: > -> `findDOMNode()` is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. However, there are some situations where this is necessary (for instance, you may need to find a DOM node in order to position it absolutely or to determine the rendered width measured in pixels). - +> `findDOMNode()` is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. > > `findDOMNode()` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown. +> +> `findDOMNode()` cannot be used on stateless components. ## ReactDOMServer diff --git a/docs/ref-03-component-specs.md b/docs/ref-03-component-specs.md index 8a851e3d..2855caa7 100644 --- a/docs/ref-03-component-specs.md +++ b/docs/ref-03-component-specs.md @@ -121,7 +121,7 @@ Invoked once, both on the client and server, immediately before the initial rend void componentDidMount() ``` -Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via `ReactDOM.findDOMNode(this)`. The `componentDidMount()` method of child components is invoked before that of parent components. +Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, you can access any refs to your children (e.g., to access the underlying DOM representation). The `componentDidMount()` method of child components is invoked before that of parent components. If you want to integrate with other JavaScript frameworks, set timers using `setTimeout` or `setInterval`, or send AJAX requests, perform those operations in this method. diff --git a/docs/tutorial.md b/docs/tutorial.md index d289ca34..44f1a831 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -529,7 +529,7 @@ Call `preventDefault()` on the event to prevent the browser's default action of ##### Refs -We use the `ref` attribute to assign a name to a child component and `this.refs` to reference the component. We can call `ReactDOM.findDOMNode(component)` on a component to get the native browser DOM element. +We use the `ref` attribute to assign a name to a child component and `this.refs` to reference the DOM node. ##### Callbacks as props