【问题标题】:React Native: onBlur fires after onPressReact Native:onBlur 在 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>

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

【问题讨论】:

    标签: reactjs react-native native


    【解决方案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 也会首先执行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2018-09-03
    • 1970-01-01
    • 2018-07-11
    • 2021-09-27
    相关资源
    最近更新 更多