如何在React Native中防止父点击事件?

时间:2018-11-09 12:21:54

标签: javascript react-native

onParentClick = () => {
  console.log('Parent is triggered');
}

onChildClick = (event) => {
  event.stopPropagation();
  console.log('Child is triggered');
}
<TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
  <View>
    <Text>How to prevent parent click event</Text>
    <TouchableOpacity onPress={(event)=> this.onChildClick(event)>
      <Text> Click Me </Text>
    </TouchableOpacity>
  </View>
</TouchableWithoutFeedback>

预期:点击“点击我”后,必须调用onChildClick()

问题:单击“ Click Me”时,将调用onParentClick()。

如何防止“点击我”中的父母点击事件?

我点击父母的结果是“触发了父母”,效果很好。

但是点击孩子,我得到的结果是“父母被触发”。

我猜onChildClick()没有被触发。

9 个答案:

答案 0 :(得分:3)

老问题,但我遇到了同样的问题,就我而言,问题是:

import {TouchableOpacity} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';

这种奇怪的输入是由于eslint的自动建议而发生的。这些库由于某种原因不能很好地配合使用,因此我将以上内容更改为:

import {TouchableOpacity, TouchableWithoutFeedback} from 'react-native';

答案 1 :(得分:2)

您可以简单地将父母的pointerEvents属性设置为“ box-none”。这样,父级将不会响应触摸事件,但其子级视图将被单击。

                **A
        -------------------
        |                 |
        B                 C
                      ---------
                      |       |
                      D       E**

@Entity
@Table()
public class A {
    @Id
    Long id;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name = "id", referencedColumnName="id",  nullable = false)
    private Set<B> b;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name = "id", referencedColumnName="ID",  nullable = false)  
    private Set<C> c;
}

@Entity
@Table()
public class B{
    @Id
    Long id;
}

@Entity
@Table()
public class C{
    @Id
    Long id;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name = "id", referencedColumnName="id",  nullable = false)
    private Set<D> D;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name = "id", referencedColumnName="ID",  nullable = false)  
    private Set<E> E;
}

@Entity
@Table()
public class D{
    @Id
    Long id;
}

@Entity
@Table()
public class E{
    @Id
    Long id;
}

答案 2 :(得分:1)

通过event.stopPropagation,您可以阻止事件向父母传播: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

传递给onClick的第一个参数是事件本身:

function onChildClick(e) {
    e.stopPropagation();
    console.log('The link was clicked.');
}

答案 3 :(得分:1)

您需要“吞下”某处的点击事件。它可以在外部TouchableWithoutFeedback中(即:将onPress={()=> this.onParentClick()}更改为onPress={(e) => e.preventDefault()},也可以将TouchableOpacity包装在另一个触摸处理程序中,如下所示。

<TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
  <View>
    <Text>How to prevent parent click event</Text>
    <TouchableWithoutFeedback onPress={(e) => e.preventDefault()}
      <TouchableOpacity onPress={(event)=> this.onChildClick(event)>
        <Text> Click Me </Text>
      </TouchableOpacity>
    </TouchableWithoutFeedback>
  </View>
</TouchableWithoutFeedback>

答案 4 :(得分:0)

您描述的行为正常。这是因为TouchableOpacityTouchableWithoutFeedback的子组件,因此click事件在树上向上传播,从而触发TouchableWithoutFeedback的click事件。为解决此问题,您可以调用event.stopPropagation()方法,该方法将阻止事件冒泡。

类似的事情应该起作用。

onChildClick = (event)=>{ //do your logic here event.stopPropagation(); }

答案 5 :(得分:0)

我遇到了类似的问题,只需使用zIndex即可解决,不仅帮助我捕获了孩子的onPress,而且还捕获了父母的onPress,我能够在一个组件中执行两种不同的操作

答案 6 :(得分:0)

一种触发方法:

const childPresses = {}
if(canChildPress) {
  childPresses.onPress = (event) => {this.onChildClick(event)}
}

return <TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
  <View>
    <Text>How to prevent parent click event</Text>
    <TouchableOpacity {...childPresses} >
      <Text> Click Me </Text>
    </TouchableOpacity>
  </View>
</TouchableWithoutFeedback>

答案 7 :(得分:0)

使用手势处理程序

中的 TouchableOpacity
import { TouchableOpacity } from "react-native-gesture-handler";

然后将您的样式更改为containerStyle

 <TouchableOpacity onPress={props.onPress} containerStyle={styles.container}>

现在一切都看起来不错了...

答案 8 :(得分:0)

您想使用 onTouchEnd 而不是按下

这将是最简单的答案:

在您希望传播停止的点的内部视图上使用它

double c = get_c();