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

前端 未结 7 1465
被撕碎了的回忆
被撕碎了的回忆 2020-12-30 06:05

  CLOSE


_onPress(e) {
         


        
相关标签:
7条回答
  • 2020-12-30 06:44

    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;
    
    0 讨论(0)
  • 2020-12-30 06:53

    Another way to solve the problem in question is by using a ref (together with createRef) like so:

      const touchableRef = React.createRef();
      return (
        <TouchableWithoutFeedback
          ref={touchableRef}
          onPress={() => /* use touchableRef.current */ undefined}
        />
      );
    

    Another advantage of doing that is that the ref can be really anything, doesn't have to be the touched node.

    0 讨论(0)
  • 2020-12-30 06:55

    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>
      )
    };
    
    0 讨论(0)
  • 2020-12-30 06:59

    The concern is about performance so I solve it with this approach

    just create a wrapper around TouchableOpacity or any clickable view

    import { TouchableOpacity } from "react-native"
    
    export const TouchableOpacityOnPressOptimized = ({ children, onPress, index }) => {
      return (
        <TouchableOpacity onPress={() => onPress(index)}>
          {children}
        </TouchableOpacity>
      )
    }
    
    const touchMe = (index) => {
        switch(index) {
           case 1: alert('index is' + index)
           case 2: alert('index is' + index)
        }
    }
    
    <TouchableOpacityOnPressOptimized index={1} onPress={touchMe}> touch me 1 </TouchableOpacityOnPressOptimized>
    
    <TouchableOpacityOnPressOptimized index={2} onPress={touchMe}> touch me 2 </TouchableOpacityOnPressOptimized>
    
    <TouchableOpacityOnPressOptimized index={3} onPress={touchMe}> touch me 3 </TouchableOpacityOnPressOptimized>
    

    this way your touchable component not re-render

    0 讨论(0)
  • 2020-12-30 07:02

    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);
    
    0 讨论(0)
  • 2020-12-30 07:02

    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.

    0 讨论(0)
提交回复
热议问题