提交表单时如何等待onBlur状态更新

时间:2020-10-10 15:32:25

标签: reactjs react-native use-state

我在ScrollView中有一个很大的窗体,将keyBoardShouldPersistTaps设置为“ handled”,并保存在TextInput中调用onBlur时输入到全局状态的值(将onChangeText保存到每个组件中的本地状态,以便进行更多操作)表演者)。

问题出在我的用户提交表单时,如果他们在仍然具有焦点的文本输入(其中有值)的情况下单击“提交”按钮,则提交调用将在没有文本输入的值的情况下运行按下了提交按钮。

所有其他文本输入中的所有其他值均已正确提交,因为该状态有时间正确更新。

如何在调用submit函数之前确保onBlur和useState(我知道是异步的)已更新?

用于解释我所面临挑战的简化代码(expo snack):

import * as React from 'react';
import { ScrollView, StyleSheet, Button, Alert, TextInput, Keyboard } from 'react-native';
import Constants from 'expo-constants';

export default function App() {
      const [globalValue, setGlobalValue] = React.useState('Useless Placeholder');
    const [localValue, setLocalValue] = React.useState(globalValue);

  return (
    <ScrollView keyboardShouldPersistTaps={"handled"} style={styles.container}>
    <TextInput
      style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
      onChangeText={text => setLocalValue(text)}
      value={localValue}
      onBlur={() => setGlobalValue(localValue)}
    />
            <Button
        title="Press me"
        onPress={() => {Keyboard.dismiss(); Alert.alert(globalValue);}}
      />
    </ScrollView>
  );
}

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

重现我的问题的步骤:

  1. 在文本输入中输入内容
  2. 直接单击“提交”按钮
  3. 您将看不到您在textinput中输入的内容,因为在状态从onBlur更新之前,提交已触发

复制工作“提交”的步骤:

  1. 在文本输入中输入内容
  2. 单击其他任何地方以关闭键盘
  3. 单击按钮,您将看到您在文本输入中输入的内容

1 个答案:

答案 0 :(得分:1)

旧代码:您不能按以下方式操作,还是必须使用另一个称为“文本”的状态变量?

export default function App() {
  const placeHolder = "Useless Placeholder";
  const [value, onChangeText] = React.useState(placeHolder);

  return (
    <ScrollView keyboardShouldPersistTaps={"handled"} style={styles.container}>
    <TextInput
      style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
      onChangeText={text => onChangeText(text)}
      value={value}
      onBlur={() => {
        onChangeText(value || placeHolder);
      }}
    />
    <Button
        title="Press me"
        onPress={() => {Keyboard.dismiss(); Alert.alert(value);}}
    />
    </ScrollView>
  );
}

更新的代码:这是我到目前为止唯一能看到的方法

export default function App() {
  const placeHolder = 'Useless Placeholder';
  const [globalValue, setGlobalValue] = React.useState(placeHolder); 
  const [localValue, setLocalValue] = React.useState(globalValue);
    
  useEffect(() => {
    Keyboard.dismiss();
    if(placeHolder !== globalValue) {
      Alert.alert(globalValue);
    }      
  }, [globalValue]);

  return (
    <ScrollView keyboardShouldPersistTaps={"handled"} style={styles.container}>
      <TextInput
        style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
        onChangeText={text => setLocalValue(text)}
        value={localValue}
      />
      <Button
        title="Press me"
        onPress={() => {setGlobalValue(localValue)}}
      />
    </ScrollView>
  );
}