Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get real elment by node id? react-native

Tags:

react-native

<TouchableHighlight onPress={this._onPress.bind(this)}>
  <Text style={{color: 'white'}}>CLOSE</Text>
</TouchableHighlight>

_onPress(e) {
  console.log(e.nativeEvent.target);
}

As above, the target is just a number called node id, but I want to get the real element. How can I do that?

like image 386
CoderLim Avatar asked Jul 29 '16 06:07

CoderLim


People also ask

Can you use get element by ID in React?

The equivalent of document. getElementById in React is refs. We can assign a ref to an element and then retrieve the element that's assigned the ref from the ref's current property. to create a ref with the useRef hook and assign it to myContainer .

How do you get element position React Native?

To get the position of an element with React Native, we can get it from the View 's onLayout callback. to add a View with the onLayout prop set to a function that gets the position values from the event. nativeEvent. layout property.

How do you get the element by reference in React?

To get an element by ID in React: Set the ref prop on the element. Use the current property to access the element in the useEffect hook.

How do I use Getelementby ID in React?

getElementById() method in React is using refs. To select an element, set the ref prop on it to the return value of calling the useRef() hook and access the dom element using the current property on the ref , e.g. ref. current .


5 Answers

In case somebody stumbles on that question, ReactNativeComponentTree was removed from version 0.56 or so.

However, I found a much cleaner way to detect a tap on a certain (sub-)element:

import React from 'React';
import {
  Text,
  TouchableOpacity,
  View,

  findNodeHandle
} from 'react-native';

class TestClass extends React.Component {
  onTap = (evt) => {
    // Retrieve the handle of the second <Text> node
    let elementHandle = findNodeHandle(this.refs["element"]);

    // Check if the tapped element's node-id equals the retrieved one 
    if (evt.nativeEvent.target == elementHandle) {
      // Do something when element was clicked
      console.log("Second <Text> node was tapped")
    }
  }

  render() {
    return (
      <TouchableOpacity onPress={this.onTap}>
        <View>
          <Text>Hi there!</Text>
          <Text ref="element">Only detect this element</Text>
        </View>
      </TouchableOpacity>
    );
  }
};

Basically, we are just using a reference (ref) to access the node-id of an element using findNodeHandle.

We then compare that node-id with the nativeEvent.target node-id in order to check if a sub-element was tapped.

In the above example, only the second <Text> node produces an output.

like image 93
YoshiJaeger Avatar answered Oct 03 '22 19:10

YoshiJaeger


The code to do it changed recently when React / React Native common code was moved around, but what I would suggest is to check out Inspector code and available methods on the ReactNativeComponentTree

More specifically, the following code should do the trick for you:

var ReactNativeComponentTree = require('react/lib/ReactNativeComponentTree');
ReactNativeComponentTree.getInstanceFromNode(nativeTag);
like image 38
Mike Grabowski Avatar answered Oct 03 '22 17:10

Mike Grabowski


This is how I ended up resolving similar situation for myself. It doesn't follow the same approach by any means but did it the trick!

onItemPressed(item) {
  this.props.navigateForward(item.sceneId);
  this.props.closeDrawer();
}

render() {
  var listItems = [];

  for (var i=0; i < this.props.navigation.scenes.length; i++) {
    var item = this.props.navigation.scenes[i];

    listItems.push(<ListItem
      onPress={this.onItemPressed.bind(this, item)}
      key={i}
      title={item.title}
      leftIcon={{name: item.icon}}
      underlayColor={colors.lightPrimary}
      containerStyle={styles.menuItemStyle}
      titleStyle={styles.menuItemTitle}
    />);
  }


  return (
    <View style={styles.container}>
      <List containerStyle={styles.listContainer}>
        {listItems}
      </List>
    </View>
  )
};
like image 31
Sunny Patel Avatar answered Oct 03 '22 18:10

Sunny Patel


In react native v.0.51 you need this statement:

import ReactNativeComponentTree from 'react-native/Libraries/Renderer/shims/ReactNativeComponentTree';
ReactNativeComponentTree.getInstanceFromNode(e.target);

and ._currentElement.props changed to .memoizedProps

like image 22
mpyw Avatar answered Oct 03 '22 18:10

mpyw


In react native v.0.42 you need this statement:

import ReactNativeComponentTree from 'react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentTree';
ReactNativeComponentTree.getInstanceFromNode(e.target)._currentElement;
like image 45
appsthatmatter Avatar answered Oct 03 '22 19:10

appsthatmatter