Skip to content

Commit e1c84f1

Browse files
authored
Docs for new DOM APIs (#4783)
* Docs for new DOM APIs * Address first round of comments * Reference new ref API in components API reference * Address feedback about examples and clarify Text component refs * Fix examples
1 parent cc1ab23 commit e1c84f1

14 files changed

+366
-5
lines changed

docs/activityindicator.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ Whether the indicator should hide when not animating.
7878

7979
---
8080

81+
### `ref`
82+
83+
A ref setter that will be assigned an [element node](element-nodes) when mounted.
84+
85+
---
86+
8187
### `size`
8288

8389
Size of the indicator.

docs/document-nodes.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
id: document-nodes
3+
title: Document nodes
4+
---
5+
6+
Document nodes represent a complete native view tree. Apps using native navigation would provide a separate document node for each screen. Apps not using native navigation would generally provide a single document for the whole app (similar to single-page apps on Web).
7+
8+
```SnackPlayer ext=js&name=Document%20instance%20example
9+
import * as React from 'react';
10+
import {Text, TextInput, View} from 'react-native';
11+
12+
function MyComponent(props) {
13+
return (
14+
<View ref={props.ref}>
15+
<Text>Start typing below</Text>
16+
<TextInput id="main-text-input" />
17+
</View>
18+
)
19+
}
20+
21+
export default function AccessingDocument() {
22+
const ref = React.useRef(null);
23+
24+
React.useEffect(() => {
25+
// Get the main text input in the screen and focus it after initial load.
26+
const element = ref.current;
27+
const doc = element.ownerDocument;
28+
const textInput = doc.getElementById('main-text-input');
29+
textInput?.focus();
30+
}, []);
31+
32+
return (
33+
<MyComponent ref={ref} />
34+
);
35+
}
36+
```
37+
38+
---
39+
40+
## Reference
41+
42+
### Web-compatible API
43+
44+
From [`Document`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement):
45+
46+
- Properties
47+
- [`childElementCount`](https://developer.mozilla.org/en-US/docs/Web/API/Document/childElementCount)
48+
- [`children`](https://developer.mozilla.org/en-US/docs/Web/API/Document/children)
49+
- [`documentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement)
50+
- [`firstElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Document/firstElementChild)
51+
- [`lastElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Document/lastElementChild)
52+
- Methods
53+
- [`getElementById()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)
54+
55+
From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
56+
57+
- Properties
58+
- [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
59+
- [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
60+
- [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
61+
- [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
62+
- [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
63+
- [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
64+
- [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
65+
- [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
66+
- [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
67+
- [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
68+
- [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
69+
- [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
70+
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
71+
- Methods
72+
- [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
73+
- [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
74+
- [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
75+
- [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)

docs/element-nodes.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
id: element-nodes
3+
title: Element nodes
4+
---
5+
6+
Element nodes represent native components in the native view tree (similar to [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) nodes on Web).
7+
8+
They are provided by all native components, and by many built-in components, via refs:
9+
10+
```SnackPlayer ext=js&name=Element%20instances%20example
11+
import * as React from 'react';
12+
import { View, SafeAreaView, StyleSheet, Text } from 'react-native';
13+
14+
const ViewWithRefs = () => {
15+
const ref = React.useRef(null);
16+
const [viewInfo, setViewInfo] = React.useState('');
17+
18+
React.useEffect(() => {
19+
// `element` is an object implementing the interface described here.
20+
const element = ref.current;
21+
const rect = JSON.stringify(element.getBoundingClientRect());
22+
setViewInfo(
23+
`Bounding rect is: ${rect}.\nText content is: ${element.textContent}`,
24+
);
25+
}, []);
26+
27+
return (
28+
<SafeAreaView style={styles.container}>
29+
<View ref={ref} style={styles.content}>
30+
<Text>Hello world!</Text>
31+
</View>
32+
<Text>{viewInfo}</Text>
33+
</SafeAreaView>
34+
);
35+
};
36+
37+
const styles = StyleSheet.create({
38+
container: {
39+
flex: 1,
40+
},
41+
content: {
42+
padding: 10,
43+
backgroundColor: 'gray',
44+
},
45+
});
46+
47+
export default ViewWithRefs;
48+
```
49+
50+
:::info
51+
Note that some built-in components are only a container for other components (including native components). For example, `ScrollView` internally renders a native scroll view and a native view, which are accessible through the ref it provides using methods like `getNativeScrollRef()` and `getInnerViewRef()`.
52+
:::
53+
54+
---
55+
56+
## Reference
57+
58+
### Web-compatible API
59+
60+
From [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement):
61+
62+
- Properties
63+
- [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)
64+
- [`offsetLeft`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft)
65+
- [`offsetParent`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent)
66+
- [`offsetTop`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop)
67+
- [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)
68+
- Methods
69+
- [`blur()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur).
70+
- [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus).
71+
- ⚠️ The `options` parameter is not supported.
72+
73+
From [`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element):
74+
75+
- Properties
76+
- [`childElementCount`](https://developer.mozilla.org/en-US/docs/Web/API/Element/childElementCount)
77+
- [`children`](https://developer.mozilla.org/en-US/docs/Web/API/Element/children)
78+
- [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
79+
- [`clientLeft`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientLeft)
80+
- [`clientTop`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientTop)
81+
- [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
82+
- [`firstElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Element/firstElementChild)
83+
- [`id`](https://developer.mozilla.org/en-US/docs/Web/API/Element/id)
84+
- ℹ️ Returns the value of the `id` or `nativeID` props.
85+
- [`lastElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Element/lastElementChild)
86+
- [`nextElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nextElementSibling)
87+
- [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeName)
88+
- [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeType)
89+
- [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeValue)
90+
- [`previousElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling)
91+
- [`scrollHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight)
92+
- [`scrollLeft`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft)
93+
- ⚠️ For built-in components, only `ScrollView` instances can return a value other than zero.
94+
- [`scrollTop`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop)
95+
- ⚠️ For built-in components, only `ScrollView` instances can return a value other than zero.
96+
- [`scrollWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth)
97+
- [`tagName`](https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName)
98+
- ℹ️ Returns a normalized native component name prefixed with `RN:`, like `RN:View`.
99+
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Element/textContent)
100+
- Methods
101+
- [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)
102+
- [`hasPointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/hasPointerCapture)
103+
- [`setPointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture)
104+
- [`releasePointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/releasePointerCapture)
105+
106+
From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
107+
108+
- Properties
109+
- [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
110+
- [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
111+
- [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
112+
- [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
113+
- [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
114+
- [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
115+
- [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
116+
- [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
117+
- [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
118+
- ℹ️ Will return the [document instance](/docs/next/document-instances) where this component was rendered.
119+
- [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
120+
- [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
121+
- [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
122+
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
123+
- Methods
124+
- [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
125+
- [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
126+
- [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
127+
- ℹ️ Will return a reference to itself if the component is not mounted.
128+
- [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)
129+
130+
### Legacy API
131+
132+
- [`measure()`](/docs/next/legacy/direct-manipulation#measurecallback)
133+
- [`measureInWindow()`](/docs/next/legacy/direct-manipulation#measureinwindowcallback)
134+
- [`measureLayout()`](/docs/next/legacy/direct-manipulation#measurelayoutrelativetonativecomponentref-onsuccess-onfail)
135+
- [`setNativeProps()`](/docs/next/legacy/direct-manipulation#setnativeprops-with-touchableopacity)

docs/image.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,12 @@ A string indicating which referrer to use when fetching the resource. Sets the v
334334

335335
---
336336

337+
### `ref`
338+
339+
A ref setter that will be assigned an [element node](element-nodes) when mounted.
340+
341+
---
342+
337343
### `resizeMethod` <div className="label android">Android</div>
338344

339345
The mechanism that should be used to resize the image when the image's dimensions differ from the image view's dimensions. Defaults to `auto`.

docs/imagebackground.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,7 @@ Inherits [Image Props](image.md#props).
7171

7272
### `imageRef`
7373

74-
Allows to set a reference to the inner `Image` component
75-
76-
| Type |
77-
| ------------------------------------------------------------- |
78-
| [Ref](https://react.dev/learn/manipulating-the-dom-with-refs) |
74+
A ref setter that will be assigned the [element node](element-nodes) of the inner `Image` component when mounted.
7975

8076
---
8177

docs/modal.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ This requires you to implement the `onRequestClose` prop to handle the dismissal
189189

190190
---
191191

192+
### `ref`
193+
194+
A ref setter that will be assigned an [element node](element-nodes) when mounted.
195+
196+
---
197+
192198
### `onRequestClose`
193199

194200
The `onRequestClose` callback is called when the user taps the hardware back button on Android or the menu button on Apple TV. Because of this required prop, be aware that `BackHandler` events will not be emitted as long as the modal is open.

docs/nodes.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
id: nodes
3+
title: Nodes from refs
4+
---
5+
6+
React Native apps render a native view tree that represents the UI, similar to how React DOM does on Web (the DOM tree). React Native provides imperative access to this tree via [refs](https://react.dev/learn/manipulating-the-dom-with-refs), which are returned by all native components (including those rendered by built-in components like [`View`](/docs/next/view)).
7+
8+
React Native provides 3 types of nodes:
9+
10+
- [Elements](/docs/next/element-nodes): element nodes represent native components in the native view tree (similar to [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) nodes on Web). They are provided by all native components via refs.
11+
- [Text](/docs/next/text-nodes): text nodes represent raw text content on the tree (similar to [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text) nodes on Web). They are not directly accessible via `refs`, but can be accessed using methods like [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) on element refs.
12+
- [Documents](/docs/next/document-nodes): document nodes represent a complete native view tree (similar to [`Document`](https://developer.mozilla.org/en-US/docs/Web/API/Document) nodes on Web). Like text nodes, they can only be accessed through other nodes, using properties like [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument).
13+
14+
As on Web, these nodes can be used to traverse the rendered UI tree, access layout information or execute imperative operations like `focus`.
15+
16+
:::info
17+
**Unlike on Web, these nodes do not allow mutation** (e.g.: [`node.appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)), as the tree contents are fully managed by the React renderer.
18+
:::

docs/switch.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ Invoked when the user tries to change the value of the switch. Receives the new
9696

9797
---
9898

99+
### `ref`
100+
101+
A ref setter that will be assigned an [element node](element-nodes) when mounted.
102+
103+
---
104+
99105
### `thumbColor`
100106

101107
Color of the foreground switch grip. If this is set on iOS, the switch grip will lose its drop shadow.

docs/text-nodes.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
id: text-nodes
3+
title: Text nodes
4+
---
5+
6+
Text nodes represent raw text content on the tree (similar to [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text) nodes on Web). They are not directly accessible via `refs`, but can be accessed using methods like [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) on element refs.
7+
8+
```SnackPlayer ext=js&name=Text%20instances%20example
9+
import * as React from 'react';
10+
import { SafeAreaView, StyleSheet, Text } from 'react-native';
11+
12+
const TextWithRefs = () => {
13+
const ref = React.useRef(null);
14+
const [viewInfo, setViewInfo] = React.useState('');
15+
16+
React.useEffect(() => {
17+
// `textElement` is an object implementing the interface described here.
18+
const textElement = ref.current;
19+
const textNode = textElement.childNodes[0];
20+
setViewInfo(
21+
`Text content is: ${textNode.nodeValue}`,
22+
);
23+
}, []);
24+
25+
return (
26+
<SafeAreaView style={styles.container}>
27+
<Text ref={ref}>
28+
Hello world!
29+
</Text>
30+
<Text>{viewInfo}</Text>
31+
</SafeAreaView>
32+
);
33+
};
34+
35+
const styles = StyleSheet.create({
36+
container: {
37+
flex: 1,
38+
},
39+
content: {
40+
padding: 10,
41+
backgroundColor: 'gray',
42+
},
43+
});
44+
45+
export default TextWithRefs;
46+
```
47+
48+
---
49+
50+
## Reference
51+
52+
### Web-compatible API
53+
54+
From [`CharacterData`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData):
55+
56+
- Properties
57+
- [`data`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/data)
58+
- [`length`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/length)
59+
- [`nextElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/nextElementSibling)
60+
- [`previousElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/previousElementSibling)
61+
- Methods
62+
- [`substringData()`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/substringData)
63+
64+
From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
65+
66+
- Properties
67+
- [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
68+
- [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
69+
- [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
70+
- [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
71+
- [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
72+
- [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
73+
- [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
74+
- [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
75+
- [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
76+
- ℹ️ Will return the [document instance](/docs/next/document-instances) where this component was rendered.
77+
- [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
78+
- [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
79+
- [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
80+
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
81+
- Methods
82+
- [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
83+
- [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
84+
- [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
85+
- ℹ️ Will return a reference to itself if the component is not mounted.
86+
- [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)

docs/text.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,14 @@ When the scroll view is disabled, this defines how far your touch may move off o
638638

639639
---
640640

641+
### `ref`
642+
643+
A ref setter that will be assigned an [element node](element-nodes) when mounted.
644+
645+
Note that `Text` components don't provide text nodes, the same way that paragraph elements (`<p>`) on Web are element nodes instead of text nodes. Text nodes can be found as their child nodes instead.
646+
647+
---
648+
641649
### `role`
642650

643651
`role` communicates the purpose of a component to the user of an assistive technology. Has precedence over the [`accessibilityRole`](text#accessibilityrole) prop.

0 commit comments

Comments
 (0)