Files
react-native/docs/direct-manipulation.html
T
Website Deployment Script 69a8ce7fab Updated docs for 0.45
2017-06-07 21:46:19 +00:00

171 lines
49 KiB
HTML

<!DOCTYPE html><html><head><title>Direct Manipulation</title><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width"><meta property="fb:app_id" content="1677033832619985"><meta property="fb:admins" content="121800083"><meta property="og:site_name" content="React Native"><meta property="og:title" content="Direct Manipulation"><meta property="og:url" content="https://facebook.github.io/react-native/index.html"><meta property="og:image" content="https://facebook.github.io/react-native/img/opengraph.png"><meta property="og:description" content="A framework for building native apps using React"><meta name="twitter:site" content="@reactnative"><meta name="twitter:card" content="summary_large_image"><meta property="og:type" content="website"><base href="/react-native/"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"><link rel="shortcut icon" href="img/favicon.png?2"><link rel="stylesheet" href="css/react-native.css"><link rel="alternate" type="application/rss+xml" title="React Native Blog" href="https://facebook.github.io/react-native/blog/feed.xml"><link href="//cdn-images.mailchimp.com/embedcode/horizontal-slim-10_7.css" rel="stylesheet" type="text/css"><script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script><script type="text/javascript">try{Typekit.load();}catch(e){}</script></head><body><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><div class="container"><div class="nav-main"><div class="wrap"><a class="nav-home" href=""><img src="img/header_logo.png">React Native</a><a class="nav-version" href="/react-native/versions.html">0.45</a><div class="nav-site-wrapper"><ul class="nav-site nav-site-internal"><li><a href="docs/getting-started.html" class="active" data-target=".nav-docs">Docs</a></li><li><a href="/react-native/support.html" class="">Help</a></li><li><a href="/react-native/showcase.html" class="">Showcase</a></li><li><a href="/react-native/blog/" class="">Blog</a></li></ul><div class="algolia-search-wrapper"><input id="algolia-doc-search" tabindex="0" type="text" placeholder="Search docs..."></div><ul class="nav-site nav-site-external"><li><a href="https://github.com/facebook/react-native" class="">GitHub</a></li><li><a href="http://facebook.github.io/react" class="">React</a></li></ul></div></div></div><section class="content wrap documentationContent"><div class="nav-docs"><div class="nav-docs-viewport"><div class="nav-docs-section"><h3>The Basics</h3><ul><li><a style="margin-left:10px;" class="" href="docs/getting-started.html">Getting Started</a></li><li><a style="margin-left:10px;" class="" href="docs/tutorial.html">Tutorial</a></li><li><a style="margin-left:10px;" class="" href="docs/props.html">Props</a></li><li><a style="margin-left:10px;" class="" href="docs/state.html">State</a></li><li><a style="margin-left:10px;" class="" href="docs/style.html">Style</a></li><li><a style="margin-left:10px;" class="" href="docs/height-and-width.html">Height and Width</a></li><li><a style="margin-left:10px;" class="" href="docs/flexbox.html">Layout with Flexbox</a></li><li><a style="margin-left:10px;" class="" href="docs/handling-text-input.html">Handling Text Input</a></li><li><a style="margin-left:10px;" class="" href="docs/handling-touches.html">Handling Touches</a></li><li><a style="margin-left:10px;" class="" href="docs/using-a-scrollview.html">Using a ScrollView</a></li><li><a style="margin-left:10px;" class="" href="docs/using-a-listview.html">Using List Views</a></li><li><a style="margin-left:10px;" class="" href="docs/network.html">Networking</a></li><li><a style="margin-left:10px;" class="" href="docs/more-resources.html">More Resources</a></li></ul></div><div class="nav-docs-section"><h3>Guides</h3><ul><li><a style="margin-left:10px;" class="" href="docs/components-and-apis.html">Components and APIs</a></li><li><a style="margin-left:10px;" class="" href="docs/platform-specific-code.html">Platform Specific Code</a></li><li><a style="margin-left:10px;" class="" href="docs/navigation.html">Navigating Between Screens</a></li><li><a style="margin-left:10px;" class="" href="docs/images.html">Images</a></li><li><a style="margin-left:10px;" class="" href="docs/animations.html">Animations</a></li><li><a style="margin-left:10px;" class="" href="docs/accessibility.html">Accessibility</a></li><li><a style="margin-left:10px;" class="" href="docs/timers.html">Timers</a></li><li><a style="margin-left:10px;" class="" href="docs/debugging.html">Debugging</a></li><li><a style="margin-left:10px;" class="" href="docs/performance.html">Performance</a></li><li><a style="margin-left:10px;" class="" href="docs/gesture-responder-system.html">Gesture Responder System</a></li><li><a style="margin-left:10px;" class="" href="docs/javascript-environment.html">JavaScript Environment</a></li><li><a style="margin-left:10px;" class="active" href="docs/direct-manipulation.html">Direct Manipulation</a></li><li><a style="margin-left:10px;" class="" href="docs/colors.html">Color Reference</a></li><li><a style="margin-left:10px;" class="" href="docs/integration-with-existing-apps.html">Integration With Existing Apps</a></li><li><a style="margin-left:10px;" class="" href="docs/running-on-device.html">Running On Device</a></li><li><a style="margin-left:10px;" class="" href="docs/upgrading.html">Upgrading to new React Native versions</a></li><li><a style="margin-left:10px;" class="" href="docs/testing.html">Running Tests and Contributing</a></li><li><a style="margin-left:10px;" class="" href="docs/understanding-cli.html">Understanding the CLI</a></li></ul></div><div class="nav-docs-section"><h3>Guides (iOS)</h3><ul><li><a style="margin-left:10px;" class="" href="docs/native-modules-ios.html">Native Modules</a></li><li><a style="margin-left:10px;" class="" href="docs/native-components-ios.html">Native UI Components</a></li><li><a style="margin-left:10px;" class="" href="docs/linking-libraries-ios.html">Linking Libraries</a></li><li><a style="margin-left:10px;" class="" href="docs/running-on-simulator-ios.html">Running On Simulator</a></li><li><a style="margin-left:10px;" class="" href="docs/communication-ios.html">Communication between native and React Native</a></li><li><a style="margin-left:10px;" class="" href="docs/building-for-apple-tv.html">Building For Apple TV</a></li></ul></div><div class="nav-docs-section"><h3>Guides (Android)</h3><ul><li><a style="margin-left:10px;" class="" href="docs/native-modules-android.html">Native Modules</a></li><li><a style="margin-left:10px;" class="" href="docs/native-components-android.html">Native UI Components</a></li><li><a style="margin-left:10px;" class="" href="docs/headless-js-android.html">Headless JS</a></li><li><a style="margin-left:10px;" class="" href="docs/signed-apk-android.html">Generating Signed APK</a></li><li><a style="margin-left:10px;" class="" href="docs/android-building-from-source.html">Building React Native from source</a></li></ul></div><div class="nav-docs-section"><h3>components</h3><ul><li><a style="margin-left:10px;" class="" href="docs/activityindicator.html">ActivityIndicator</a></li><li><a style="margin-left:10px;" class="" href="docs/button.html">Button</a></li><li><a style="margin-left:10px;" class="" href="docs/datepickerios.html">DatePickerIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/drawerlayoutandroid.html">DrawerLayoutAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/flatlist.html">FlatList</a></li><li><a style="margin-left:10px;" class="" href="docs/image.html">Image</a></li><li><a style="margin-left:10px;" class="" href="docs/keyboardavoidingview.html">KeyboardAvoidingView</a></li><li><a style="margin-left:10px;" class="" href="docs/listview.html">ListView</a></li><li><a style="margin-left:10px;" class="" href="docs/modal.html">Modal</a></li><li><a style="margin-left:10px;" class="" href="docs/navigatorios.html">NavigatorIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/picker.html">Picker</a></li><li><a style="margin-left:10px;" class="" href="docs/pickerios.html">PickerIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/progressbarandroid.html">ProgressBarAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/progressviewios.html">ProgressViewIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/refreshcontrol.html">RefreshControl</a></li><li><a style="margin-left:10px;" class="" href="docs/scrollview.html">ScrollView</a></li><li><a style="margin-left:10px;" class="" href="docs/sectionlist.html">SectionList</a></li><li><a style="margin-left:10px;" class="" href="docs/segmentedcontrolios.html">SegmentedControlIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/slider.html">Slider</a></li><li><a style="margin-left:10px;" class="" href="docs/snapshotviewios.html">SnapshotViewIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/statusbar.html">StatusBar</a></li><li><a style="margin-left:10px;" class="" href="docs/switch.html">Switch</a></li><li><a style="margin-left:10px;" class="" href="docs/tabbarios.html">TabBarIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/tabbarios-item.html">TabBarIOS.Item</a></li><li><a style="margin-left:10px;" class="" href="docs/text.html">Text</a></li><li><a style="margin-left:10px;" class="" href="docs/textinput.html">TextInput</a></li><li><a style="margin-left:10px;" class="" href="docs/toolbarandroid.html">ToolbarAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/touchablehighlight.html">TouchableHighlight</a></li><li><a style="margin-left:10px;" class="" href="docs/touchablenativefeedback.html">TouchableNativeFeedback</a></li><li><a style="margin-left:10px;" class="" href="docs/touchableopacity.html">TouchableOpacity</a></li><li><a style="margin-left:10px;" class="" href="docs/touchablewithoutfeedback.html">TouchableWithoutFeedback</a></li><li><a style="margin-left:10px;" class="" href="docs/view.html">View</a></li><li><a style="margin-left:10px;" class="" href="docs/viewpagerandroid.html">ViewPagerAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/virtualizedlist.html">VirtualizedList</a></li><li><a style="margin-left:10px;" class="" href="docs/webview.html">WebView</a></li></ul></div><div class="nav-docs-section"><h3>APIs</h3><ul><li><a style="margin-left:10px;" class="" href="docs/accessibilityinfo.html">AccessibilityInfo</a></li><li><a style="margin-left:10px;" class="" href="docs/actionsheetios.html">ActionSheetIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/adsupportios.html">AdSupportIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/alert.html">Alert</a></li><li><a style="margin-left:10px;" class="" href="docs/alertios.html">AlertIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/animated.html">Animated</a></li><li><a style="margin-left:10px;" class="" href="docs/appregistry.html">AppRegistry</a></li><li><a style="margin-left:10px;" class="" href="docs/appstate.html">AppState</a></li><li><a style="margin-left:10px;" class="" href="docs/asyncstorage.html">AsyncStorage</a></li><li><a style="margin-left:10px;" class="" href="docs/backandroid.html">BackAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/backhandler.html">BackHandler</a></li><li><a style="margin-left:10px;" class="" href="docs/cameraroll.html">CameraRoll</a></li><li><a style="margin-left:10px;" class="" href="docs/clipboard.html">Clipboard</a></li><li><a style="margin-left:10px;" class="" href="docs/datepickerandroid.html">DatePickerAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/dimensions.html">Dimensions</a></li><li><a style="margin-left:10px;" class="" href="docs/easing.html">Easing</a></li><li><a style="margin-left:10px;" class="" href="docs/geolocation.html">Geolocation</a></li><li><a style="margin-left:10px;" class="" href="docs/imageeditor.html">ImageEditor</a></li><li><a style="margin-left:10px;" class="" href="docs/imagepickerios.html">ImagePickerIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/imagestore.html">ImageStore</a></li><li><a style="margin-left:10px;" class="" href="docs/interactionmanager.html">InteractionManager</a></li><li><a style="margin-left:10px;" class="" href="docs/keyboard.html">Keyboard</a></li><li><a style="margin-left:10px;" class="" href="docs/layoutanimation.html">LayoutAnimation</a></li><li><a style="margin-left:10px;" class="" href="docs/linking.html">Linking</a></li><li><a style="margin-left:10px;" class="" href="docs/nativemethodsmixin.html">NativeMethodsMixin</a></li><li><a style="margin-left:10px;" class="" href="docs/netinfo.html">NetInfo</a></li><li><a style="margin-left:10px;" class="" href="docs/panresponder.html">PanResponder</a></li><li><a style="margin-left:10px;" class="" href="docs/permissionsandroid.html">PermissionsAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/pixelratio.html">PixelRatio</a></li><li><a style="margin-left:10px;" class="" href="docs/pushnotificationios.html">PushNotificationIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/settings.html">Settings</a></li><li><a style="margin-left:10px;" class="" href="docs/share.html">Share</a></li><li><a style="margin-left:10px;" class="" href="docs/statusbarios.html">StatusBarIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/stylesheet.html">StyleSheet</a></li><li><a style="margin-left:10px;" class="" href="docs/systrace.html">Systrace</a></li><li><a style="margin-left:10px;" class="" href="docs/timepickerandroid.html">TimePickerAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/toastandroid.html">ToastAndroid</a></li><li><a style="margin-left:10px;" class="" href="docs/vibration.html">Vibration</a></li><li><a style="margin-left:10px;" class="" href="docs/vibrationios.html">VibrationIOS</a></li><li><a style="margin-left:10px;" class="" href="docs/layout-props.html">Layout Props</a></li><li><a style="margin-left:10px;" class="" href="docs/shadow-props.html">Shadow Props</a></li></ul></div></div></div><div class="inner-content"><a id="content"></a><h1><a class="anchor" name="direct-manipulation"></a>Direct Manipulation <a class="hash-link" href="docs/direct-manipulation.html#direct-manipulation">#</a></h1><div><p>It is sometimes necessary to make changes directly to a component
without using state/props to trigger a re-render of the entire subtree.
When using React in the browser for example, you sometimes need to
directly modify a DOM node, and the same is true for views in mobile
apps. <code>setNativeProps</code> is the React Native equivalent to setting
properties directly on a DOM node.</p><blockquote><p>Use setNativeProps when frequent re-rendering creates a performance bottleneck</p><p>Direct manipulation will not be a tool that you reach for
frequently; you will typically only be using it for creating
continuous animations to avoid the overhead of rendering the component
hierarchy and reconciling many views. <code>setNativeProps</code> is imperative
and stores state in the native layer (DOM, UIView, etc.) and not
within your React components, which makes your code more difficult to
reason about. Before you use it, try to solve your problem with <code>setState</code>
and <a href="http://facebook.github.io/react/docs/advanced-performance.html#shouldcomponentupdate-in-action" target="_blank">shouldComponentUpdate</a>.</p></blockquote><h2><a class="anchor" name="setnativeprops-with-touchableopacity"></a>setNativeProps with TouchableOpacity <a class="hash-link" href="docs/direct-manipulation.html#setnativeprops-with-touchableopacity">#</a></h2><p><a href="https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableOpacity.js" target="_blank">TouchableOpacity</a>
uses <code>setNativeProps</code> internally to update the opacity of its child
component:</p><div class="prism language-javascript"><span class="token function">setOpacityTo<span class="token punctuation">(</span></span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // Redacted: animation related code
</span> <span class="token keyword">this</span><span class="token punctuation">.</span>refs<span class="token punctuation">[</span>CHILD_REF<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">setNativeProps<span class="token punctuation">(</span></span><span class="token punctuation">{</span>
opacity<span class="token punctuation">:</span> value
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span></div><p>This allows us to write the following code and know that the child will
have its opacity updated in response to taps, without the child having
any knowledge of that fact or requiring any changes to its implementation:</p><div class="prism language-javascript">&lt;TouchableOpacity onPress<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>_handlePress<span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;View style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>button<span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;Text<span class="token operator">&gt;</span>Press me<span class="token operator">!</span>&lt;<span class="token operator">/</span>Text<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>View<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>TouchableOpacity<span class="token operator">&gt;</span></div><p>Let&#x27;s imagine that <code>setNativeProps</code> was not available. One way that we
might implement it with that constraint is to store the opacity value
in the state, then update that value whenever <code>onPress</code> is fired:</p><div class="prism language-javascript"><span class="token function">constructor<span class="token punctuation">(</span></span>props<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">super<span class="token punctuation">(</span></span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> myButtonOpacity<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;TouchableOpacity onPress<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState<span class="token punctuation">(</span></span><span class="token punctuation">{</span>myButtonOpacity<span class="token punctuation">:</span> <span class="token number">0.5</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
onPressOut<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState<span class="token punctuation">(</span></span><span class="token punctuation">{</span>myButtonOpacity<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;View style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">[</span>styles<span class="token punctuation">.</span>button<span class="token punctuation">,</span> <span class="token punctuation">{</span>opacity<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>myButtonOpacity<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;Text<span class="token operator">&gt;</span>Press me<span class="token operator">!</span>&lt;<span class="token operator">/</span>Text<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>View<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>TouchableOpacity<span class="token operator">&gt;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span></div><p>This is computationally intensive compared to the original example -
React needs to re-render the component hierarchy each time the opacity
changes, even though other properties of the view and its children
haven&#x27;t changed. Usually this overhead isn&#x27;t a concern but when
performing continuous animations and responding to gestures, judiciously
optimizing your components can improve your animations&#x27; fidelity.</p><p>If you look at the implementation of <code>setNativeProps</code> in
<a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js" target="_blank">NativeMethodsMixin.js</a>
you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> -
this is the exact same function call that results from re-rendering -
see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js" target="_blank">receiveComponent in
ReactNativeBaseComponent.js</a>.</p><h2><a class="anchor" name="composite-components-and-setnativeprops"></a>Composite components and setNativeProps <a class="hash-link" href="docs/direct-manipulation.html#composite-components-and-setnativeprops">#</a></h2><p>Composite components are not backed by a native view, so you cannot call
<code>setNativeProps</code> on them. Consider this example:</p><div class="snack-player"><div class="mobile-friendly-snack" style="display:none;"><div class="prism language-javascript">import React from <span class="token string">&#x27;react&#x27;</span><span class="token punctuation">;</span>
import <span class="token punctuation">{</span> Text<span class="token punctuation">,</span> TouchableOpacity<span class="token punctuation">,</span> View <span class="token punctuation">}</span> from <span class="token string">&#x27;react-native&#x27;</span><span class="token punctuation">;</span>
class <span class="token class-name">MyButton</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;View<span class="token operator">&gt;</span>
&lt;Text<span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>label<span class="token punctuation">}</span>&lt;<span class="token operator">/</span>Text<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
export default class <span class="token class-name">App</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;TouchableOpacity<span class="token operator">&gt;</span>
&lt;MyButton label<span class="token operator">=</span><span class="token string">&quot;Press me!&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>TouchableOpacity<span class="token operator">&gt;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div></div><div class="desktop-friendly-snack" style="margin-top:15px;margin-bottom:15px;"><div data-snack-name="setNativeProps with Composite Components" data-snack-description="Example usage" data-snack-code="import%20React%20from%20&#x27;react&#x27;%3B%0Aimport%20%7B%20Text%2C%20TouchableOpacity%2C%20View%20%7D%20from%20&#x27;react-native&#x27;%3B%0A%0Aclass%20MyButton%20extends%20React.Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%3E%0A%20%20%20%20%20%20%20%20%3CText%3E%7Bthis.props.label%7D%3C%2FText%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%0A%20%20%7D%0A%7D%0A%0Aexport%20default%20class%20App%20extends%20React.Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CMyButton%20label%3D%22Press%20me!%22%20%2F%3E%0A%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20)%0A%20%20%7D%0A%7D" data-snack-platform="ios" data-snack-preview="true" data-snack-sdk-version="16.0.0" style="overflow:hidden;background:#fafafa;border:1px solid rgba(0,0,0,.16);border-radius:4px;height:514px;width:880px;"></div></div></div><p>If you run this you will immediately see this error: <code>Touchable child
must either be native or forward setNativeProps to a native component</code>.
This occurs because <code>MyButton</code> isn&#x27;t directly backed by a native view
whose opacity should be set. You can think about it like this: if you
define a component with <code>React.createClass</code> you would not expect to be
able to set a style prop on it and have that work - you would need to
pass the style prop down to a child, unless you are wrapping a native
component. Similarly, we are going to forward <code>setNativeProps</code> to a
native-backed child component.</p><h4><a class="anchor" name="forward-setnativeprops-to-a-child"></a>Forward setNativeProps to a child <a class="hash-link" href="docs/direct-manipulation.html#forward-setnativeprops-to-a-child">#</a></h4><p>All we need to do is provide a <code>setNativeProps</code> method on our component
that calls <code>setNativeProps</code> on the appropriate child with the given
arguments.</p><div class="snack-player"><div class="mobile-friendly-snack" style="display:none;"><div class="prism language-javascript">import React from <span class="token string">&#x27;react&#x27;</span><span class="token punctuation">;</span>
import <span class="token punctuation">{</span> Text<span class="token punctuation">,</span> TouchableOpacity<span class="token punctuation">,</span> View <span class="token punctuation">}</span> from <span class="token string">&#x27;react-native&#x27;</span><span class="token punctuation">;</span>
class <span class="token class-name">MyButton</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
setNativeProps <span class="token operator">=</span> <span class="token punctuation">(</span>nativeProps<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>_root<span class="token punctuation">.</span><span class="token function">setNativeProps<span class="token punctuation">(</span></span>nativeProps<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;View ref<span class="token operator">=</span><span class="token punctuation">{</span>component <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_root <span class="token operator">=</span> component<span class="token punctuation">}</span> <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;Text<span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>label<span class="token punctuation">}</span>&lt;<span class="token operator">/</span>Text<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
export default class <span class="token class-name">App</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;TouchableOpacity<span class="token operator">&gt;</span>
&lt;MyButton label<span class="token operator">=</span><span class="token string">&quot;Press me!&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>TouchableOpacity<span class="token operator">&gt;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div></div><div class="desktop-friendly-snack" style="margin-top:15px;margin-bottom:15px;"><div data-snack-name="Forwarding setNativeProps" data-snack-description="Example usage" data-snack-code="import%20React%20from%20&#x27;react&#x27;%3B%0Aimport%20%7B%20Text%2C%20TouchableOpacity%2C%20View%20%7D%20from%20&#x27;react-native&#x27;%3B%0A%0Aclass%20MyButton%20extends%20React.Component%20%7B%0A%20%20setNativeProps%20%3D%20(nativeProps)%20%3D%3E%20%7B%0A%20%20%20%20this._root.setNativeProps(nativeProps)%3B%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20ref%3D%7Bcomponent%20%3D%3E%20this._root%20%3D%20component%7D%20%7B...this.props%7D%3E%0A%20%20%20%20%20%20%20%20%3CText%3E%7Bthis.props.label%7D%3C%2FText%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%0A%20%20%7D%0A%7D%0A%0Aexport%20default%20class%20App%20extends%20React.Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CMyButton%20label%3D%22Press%20me!%22%20%2F%3E%0A%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20)%0A%20%20%7D%0A%7D" data-snack-platform="ios" data-snack-preview="true" data-snack-sdk-version="16.0.0" style="overflow:hidden;background:#fafafa;border:1px solid rgba(0,0,0,.16);border-radius:4px;height:514px;width:880px;"></div></div></div><p>You can now use <code>MyButton</code> inside of <code>TouchableOpacity</code>! A sidenote for
clarity: we used the <a href="https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute" target="_blank">ref callback</a> syntax here, rather than the traditional string-based ref.</p><p>You may have noticed that we passed all of the props down to the child
view using <code>{...this.props}</code>. The reason for this is that
<code>TouchableOpacity</code> is actually a composite component, and so in addition
to depending on <code>setNativeProps</code> on its child, it also requires that the
child perform touch handling. To do this, it passes on <a href="docs/view.html#onmoveshouldsetresponder" target="_blank">various
props</a>
that call back to the <code>TouchableOpacity</code> component.
<code>TouchableHighlight</code>, in contrast, is backed by a native view and only
requires that we implement <code>setNativeProps</code>.</p><h2><a class="anchor" name="setnativeprops-to-clear-textinput-value"></a>setNativeProps to clear TextInput value <a class="hash-link" href="docs/direct-manipulation.html#setnativeprops-to-clear-textinput-value">#</a></h2><p>Another very common use case of <code>setNativeProps</code> is to clear the value
of a TextInput. The <code>controlled</code> prop of TextInput can sometimes drop
characters when the <code>bufferDelay</code> is low and the user types very
quickly. Some developers prefer to skip this prop entirely and instead
use <code>setNativeProps</code> to directly manipulate the TextInput value when
necessary. For example, the following code demonstrates clearing the
input when you tap a button:</p><div class="snack-player"><div class="mobile-friendly-snack" style="display:none;"><div class="prism language-javascript">import React from <span class="token string">&#x27;react&#x27;</span><span class="token punctuation">;</span>
import <span class="token punctuation">{</span> TextInput<span class="token punctuation">,</span> Text<span class="token punctuation">,</span> TouchableOpacity<span class="token punctuation">,</span> View <span class="token punctuation">}</span> from <span class="token string">&#x27;react-native&#x27;</span><span class="token punctuation">;</span>
export default class <span class="token class-name">App</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
clearText <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>_textInput<span class="token punctuation">.</span><span class="token function">setNativeProps<span class="token punctuation">(</span></span><span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">&#x27;&#x27;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
&lt;View style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;TextInput
ref<span class="token operator">=</span><span class="token punctuation">{</span>component <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_textInput <span class="token operator">=</span> component<span class="token punctuation">}</span>
style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>height<span class="token punctuation">:</span> <span class="token number">50</span><span class="token punctuation">,</span> flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> marginHorizontal<span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">,</span> borderWidth<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> borderColor<span class="token punctuation">:</span> <span class="token string">&#x27;#ccc&#x27;</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token operator">/</span><span class="token operator">&gt;</span>
&lt;TouchableOpacity onPress<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>clearText<span class="token punctuation">}</span><span class="token operator">&gt;</span>
&lt;Text<span class="token operator">&gt;</span>Clear text&lt;<span class="token operator">/</span>Text<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>TouchableOpacity<span class="token operator">&gt;</span>
&lt;<span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div></div><div class="desktop-friendly-snack" style="margin-top:15px;margin-bottom:15px;"><div data-snack-name="Clear text" data-snack-description="Example usage" data-snack-code="import%20React%20from%20&#x27;react&#x27;%3B%0Aimport%20%7B%20TextInput%2C%20Text%2C%20TouchableOpacity%2C%20View%20%7D%20from%20&#x27;react-native&#x27;%3B%0A%0Aexport%20default%20class%20App%20extends%20React.Component%20%7B%0A%20%20clearText%20%3D%20()%20%3D%3E%20%7B%0A%20%20%20%20this._textInput.setNativeProps(%7Btext%3A%20&#x27;&#x27;%7D)%3B%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CTextInput%0A%20%20%20%20%20%20%20%20%20%20ref%3D%7Bcomponent%20%3D%3E%20this._textInput%20%3D%20component%7D%0A%20%20%20%20%20%20%20%20%20%20style%3D%7B%7Bheight%3A%2050%2C%20flex%3A%201%2C%20marginHorizontal%3A%2020%2C%20borderWidth%3A%201%2C%20borderColor%3A%20&#x27;%23ccc&#x27;%7D%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis.clearText%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CText%3EClear%20text%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D" data-snack-platform="ios" data-snack-preview="true" data-snack-sdk-version="16.0.0" style="overflow:hidden;background:#fafafa;border:1px solid rgba(0,0,0,.16);border-radius:4px;height:514px;width:880px;"></div></div></div><h2><a class="anchor" name="avoiding-conflicts-with-the-render-function"></a>Avoiding conflicts with the render function <a class="hash-link" href="docs/direct-manipulation.html#avoiding-conflicts-with-the-render-function">#</a></h2><p>If you update a property that is also managed by the render function,
you might end up with some unpredictable and confusing bugs because
anytime the component re-renders and that property changes, whatever
value was previously set from <code>setNativeProps</code> will be completely
ignored and overridden.</p><h2><a class="anchor" name="setnativeprops-shouldcomponentupdate"></a>setNativeProps &amp; shouldComponentUpdate <a class="hash-link" href="docs/direct-manipulation.html#setnativeprops-shouldcomponentupdate">#</a></h2><p>By <a href="https://facebook.github.io/react/docs/advanced-performance.html#avoiding-reconciling-the-dom" target="_blank">intelligently applying
<code>shouldComponentUpdate</code></a>
you can avoid the unnecessary overhead involved in reconciling unchanged
component subtrees, to the point where it may be performant enough to
use <code>setState</code> instead of <code>setNativeProps</code>.</p><h2><a class="anchor" name="other-native-methods"></a>Other native methods <a class="hash-link" href="docs/direct-manipulation.html#other-native-methods">#</a></h2><p>The methods described here are available on most of the default components provided by React Native. Note, however, that they are <em>not</em> available on composite components that aren&#x27;t directly backed by a native view. This will generally include most components that you define in your own app.</p><h3><a class="anchor" name="measure-callback"></a>measure(callback) <a class="hash-link" href="docs/direct-manipulation.html#measure-callback">#</a></h3><p>Determines the location on screen, width, and height of the given view and returns the values via an async callback. If successful, the callback will be called with the following arguments:</p><ul><li>x</li><li>y</li><li>width</li><li>height</li><li>pageX</li><li>pageY</li></ul><p>Note that these measurements are not available until after the rendering has been completed in native. If you need the measurements as soon as possible, consider using the <a href="docs/view.html#onlayout" target="_blank"><code>onLayout</code> prop</a> instead.</p><h3><a class="anchor" name="measureinwindow-callback"></a>measureInWindow(callback) <a class="hash-link" href="docs/direct-manipulation.html#measureinwindow-callback">#</a></h3><p>Determines the location of the given view in the window and returns the values via an async callback. If the React root view is embedded in another native view, this will give you the absolute coordinates. If successful, the callback will be called with the following arguments:</p><ul><li>x</li><li>y</li><li>width</li><li>height</li></ul><h3><a class="anchor" name="measurelayout-relativetonativenode-onsuccess-onfail"></a>measureLayout(relativeToNativeNode, onSuccess, onFail) <a class="hash-link" href="docs/direct-manipulation.html#measurelayout-relativetonativenode-onsuccess-onfail">#</a></h3><p>Like <code>measure()</code>, but measures the view relative an ancestor, specified as <code>relativeToNativeNode</code>. This means that the returned x, y are relative to the origin x, y of the ancestor view.</p><p>As always, to obtain a native node handle for a component, you can use <code>ReactNative.findNodeHandle(component)</code>.</p><h3><a class="anchor" name="focus"></a>focus() <a class="hash-link" href="docs/direct-manipulation.html#focus">#</a></h3><p>Requests focus for the given input or view. The exact behavior triggered will depend on the platform and type of view.</p><h3><a class="anchor" name="blur"></a>blur() <a class="hash-link" href="docs/direct-manipulation.html#blur">#</a></h3><p>Removes focus from an input or view. This is the opposite of <code>focus()</code>.</p></div><div class="docs-prevnext"><a class="docs-prev" href="docs/javascript-environment.html#content">← Prev</a><a class="docs-next" href="docs/colors.html#content">Next →</a></div><p class="edit-page-block">You can <a target="_blank" href="https://github.com/facebook/react-native/blob/master/docs/DirectManipulation.md">edit the content above on GitHub</a> and send us a pull request!</p></div></section><footer class="nav-footer"><section class="sitemap"><a href="/react-native" class="nav-home"><img src="img/header_logo.png" alt="React Native" width="66" height="58"></a><div><h5><a href="docs/">Docs</a></h5><a href="docs/getting-started.html">Getting Started</a><a href="docs/tutorial.html">Tutorial</a><a href="docs/integration-with-existing-apps.html">Integration With Existing Apps</a><a href="docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/support.html">Community</a></h5><a href="/react-native/showcase.html">Showcase</a><a href="http://www.meetup.com/topics/react-native/" target="_blank">Upcoming Events</a><a href="https://www.facebook.com/groups/react.native.community" target="_blank">Facebook Group</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a></div><div><h5><a href="/react-native/support.html">Help</a></h5><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a><a href="/react-native/versions.html" target="_blank">Latest Releases</a><a href="https://react-native.canny.io/feature-requests" target="_blank">Feature Requests</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://facebook.github.io/react/" target="_blank">React</a></div></section><section class="newsletter"><div id="mc_embed_signup"><form action="//reactnative.us10.list-manage.com/subscribe/post?u=db0dd948e2b729ee62625b1a8&amp;id=47cd41008f" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate><div id="mc_embed_signup_scroll"><label for="mce-EMAIL"><h5>Get the React Native Newsletter</h5></label><input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required><div style="position:absolute;left:-5000px;" aria-hidden="true"><input type="text" name="b_db0dd948e2b729ee62625b1a8_47cd41008f" tabindex="-1" value=""></div><div class="clear"><input type="submit" value="Sign up" name="subscribe" id="mc-embedded-subscribe" class="button"></div></div></form></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"></a><section class="copyright">Copyright © 2017 Facebook Inc.</section></footer></div><div id="fb-root"></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41298772-2', 'facebook.github.io');
ga('send', 'pageview');
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)
){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
docsearch({
apiKey: '2c98749b4a1e588efec53b2acec13025',
indexName: 'react-native-versions',
inputSelector: '#algolia-doc-search',
algoliaOptions: { facetFilters: [ "tags:0.45" ], hitsPerPage: 5 }
});
</script><script src="js/scripts.js"></script><script type="text/javascript" src="//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js"></script><script type="text/javascript">(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';}(jQuery));var $mcj = jQuery.noConflict(true);</script><script type="text/javascript" src="https://snack.expo.io/embed.js"></script></body></html>