React Native:onBlur 在 onPress 之后触发

Posted

技术标签:

【中文标题】React Native:onBlur 在 onPress 之后触发【英文标题】:React Native: onBlur fires after onPress 【发布时间】:2021-03-02 17:05:09 【问题描述】:

我在 ScrollView 中有一个 TouchableOpacity 和一个 TextInput,当 TextInput 聚焦时,我按下 TouchableOpacity 我想触发 首先触发 onBlur,然后触发 onPress。发生什么了?使用 keyboardShouldPersistTaps="never" 时 onPress 根本不会执行,使用 "handled" 时 onBlur 根本不会执行,输入也不会失去焦点。我注意到从'react-native-gesture-handler'而不是'react-native'导入的TouchableOpacity,并且keyboardShouldPersistTaps“从不”onPress和onBlur都会执行,但这里的问题是onBlur在onPress之后出现!有什么解决办法吗?

<ScrollView keyboardShouldPersistTaps="never">
  <TouchableOpacity onPress=() => console.log('press')>
    <Text>Click me</Text>
  </TouchableOpacity>
  <TextInput value=value onBlur=() => console.log('blur') />
</ScrollView>

以字段为中心并按下可触摸的预期输出:

blur
press

编辑:更复杂的场景

//one component
<ScrollView keyboardShouldPersistTaps="handled">
  <TextInput value=value onBlur=() => console.log('blur') /> 
  <TextInput value=value onBlur=() => console.log('blur') /> 
  <TextInput value=value onBlur=() => console.log('blur') /> 
</ScrollView>

//another component
<TouchableOpacity onPress=() => console.log('press')>
    <Text>Click me</Text>
</TouchableOpacity>

两个组件都将在一个更大的组件中呈现。

【问题讨论】:

【参考方案1】:

您可以使用keyboardShouldPersistTaps="handled" 并在onPress 处理程序中手动触发blur。这不是完美的解决方案,但可能就足够了。

import * as React from 'react';
import 
  Text,
  View,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  TextInput,
 from 'react-native';
import Constants from 'expo-constants';

export default function App() 
  const [value, setValue] = React.useState();
  const input = React.useRef();

  return (
    <View style=styles.container>
      <ScrollView keyboardShouldPersistTaps="handled">
        <TouchableOpacity
          onPress=() => 
            input.current.blur();
            console.log('press');
          >
          <Text>Click me</Text>
        </TouchableOpacity>
        <TextInput
          ref=input
          value=value
          onBlur=() => console.log('blur')
        />
      </ScrollView>
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  ,
);

编辑:更复杂的场景 - 您可以使用 Keyboard 模块关闭键盘,这将自动在您的输入上触发模糊事件。

import * as React from 'react';
import 
  Text,
  View,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  TextInput,
  Keyboard,
 from 'react-native';
import Constants from 'expo-constants';

export default function App() 
  const [value, setValue] = React.useState();

  return (
    <View style=styles.container>
      <ScrollView keyboardShouldPersistTaps="handled">
        <TextInput value=value onBlur=() => console.log('blur') />
        <TextInput value=value onBlur=() => console.log('blur') />
        <TextInput value=value onBlur=() => console.log('blur') />
      </ScrollView>
      <TouchableOpacity
        onPress=() => 
          Keyboard.dismiss();
          console.log('press');
        >
        <Text>Click me</Text>
      </TouchableOpacity>
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  ,
);

【讨论】:

好的,在我的示例这样的简单案例中,这是一个很好的解决方案,但是如果可触摸位于它自己的 ScrollView 上完全不同的组件中并且我有多个输入,会发生什么情况?我添加了第二个示例 非常感谢您的回答,但解雇似乎并没有解决我的问题,因为即使使用 Keyboard.dismiss,onPress 也会首先执行

以上是关于React Native:onBlur 在 onPress 之后触发的主要内容,如果未能解决你的问题,请参考以下文章

在 JSX 和 React 中使用 onBlur

React - 带有 onBlur 事件的 ul 阻止 onClick 在 li 上触发

React onBlur回调中使用document.activeElement返回body解决方案

react js中的window.onblur事件没有在android webview中被调用

react-hook-form:使用 onBlur 模式时验证不起作用

React Formik:如何使用自定义 onChange 和 onBlur