reactjs - 在嵌套的功能组件 React Native 中键入 TextInput 时键盘关闭

标签 reactjs forms react-native nested react-native-textinput

我有一个奇怪的问题,当 TextInput 放置在子功能组件中时,键盘在打字时一直关闭。如果 TextInput 直接放在父组件下,则不存在此问题。这是我的代码

const SignInScreenC = props => {

// define Hook states here    
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [isEmailEmpty,setIsEmailEmpty] = useState(false);
const [isEmailValid,setIsEmailValid] = useState(true);
const [isPasswordEmpty,setIsPasswordEmpty] = useState(false);


/**
 * Called when Sign in is clicked.
 * checks if the form is valid
 */
 const _OnSignInClicked = () => {
   if(_isFormValid()) {
    //make api call
   }
 }

/* Checks if the form is valid
*/
const _isFormValid = () => {
   //reset values 
   setIsEmailEmpty(false);
   setIsEmailValid(true);
   setIsPasswordEmpty(false);

   let isValid = true;
   if(email.trim() === "") {
      setIsEmailEmpty(true);
      isValid = false;
    }
   else if(!AppUtils.isEmailValid(email)) {
      setIsEmailValid(false);
      isValid = false;
   }
   else if(password.trim() === "") {
      setIsPasswordEmpty(true);
      isValid = false;
   }
 return isValid;
}


const SignInForm = () => {
  return (

    <View style={styles.formStyle}>
    <TextInput
       key="email"
       label={Strings.hint_email}
       value={email}
       keyboardType="email-address"                            
       onChangeText={(text)=>  {
           setEmail(text)
           setIsEmailEmpty(false)
           setIsEmailValid(true)
       }}
       style={styles.marginStyle}
       autoCompleteType = "off"
       scrollEnabled = {false}
       autoCorrect={false}
       autoCapitalize={false}/>

       <TextInput
        key="pass"
        value={password}
        secureTextEntry ={true}
        label={Strings.hint_password}
        style={[styles.marginStyle,styles.stylePassword]}
        onChangeText={(text)=> {
             setPassword(text)
             setIsPasswordEmpty(false)}
        }
        theme="light"
        autoCompleteType = "off"
        scrollEnabled = {false}
        autoCorrect={false}
        autoCapitalize={false}/>
        <Button 
            style={styles.loginStyle}
            title = {Strings.login}
            onPressButton = {() => _OnSignInClicked()}/>

    </View>
  );
}

return ( 

    <>

        <ImageBackground source={Images.screen_backgound} style={{width: '100%', 
          height: '100%'}}>
            <View style = {styles.viewOverlaystyle} />
            <ScrollView  contentContainerStyle = {{flexGrow:1}} 
                keyboardShouldPersistTaps={'handled'}>
                <View style={styles.containerStyle}>
                    <SignInForm/>
                </View>
            </ScrollView>
        </ImageBackground>

    </>
 );
}

const styles = StyleSheet.create({
   ....
})

const mapStateToProps = state => ({
   userData : state.userData
});

const mapDispatchToProps = dispatch =>
    bindActionCreators(UserActions, dispatch);

 const SignInScreen = connect(mapStateToProps,mapDispatchToProps) (SignInScreenC)

 export {SignInScreen};

如果我将所有内容 直接粘贴到渲染方法,则一切正常。

最佳答案

您的 SignInForm 函数(它被视为 React 组件,因为它大写并称为 JSX)在您的 SignInScreenC 组件中声明。这意味着每次渲染,都会创建 React 组件的新 类型

  • SignInScreenC 第一次渲染:创建 SignInForm 组件,实例化它并渲染它
  • SignInScreenC 第二次渲染:创建 另一个完全不同的 SignInForm 组件,再次实例化它,有效地卸载旧的 SignInForm 并在
  • 的位置渲染新的 SignInForm
  • 因为旧的输入被卸载了,你失去了键盘焦点

  • 这是由于 React 处理渲染的方式:每当遇到不同类型的元素应该被渲染来代替旧元素时,旧元素将被卸载。作为 react ,每个新的 SignInForm 都与前一个不同,因为您不断地创建新函数

    解决方案:
  • SignInForm 之外创建单独的 SignInScreenC 组件并将所有必要的数据作为 Prop 传递
  • 或者,而不是 const SignInForm = () => return (...) 使用 const renderSignInForm = () => return (...) ,并且在渲染时,而不是 <SignInForm/>{renderSignInForm()} 一样调用它。这样它就不会被当作组件对待,也不会成为卸载
  • 的对象

    关于reactjs - 在嵌套的功能组件 React Native 中键入 TextInput 时键盘关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59891992/

    相关文章:

    forms - 如何在 Magento 中的表单提交错误后预先填写自定义表单?

    javascript - 具有动态输入值的 Angular 形式

    javascript - React Redux 使用连接组件的 HOC

    html - 滚动条没有一直滚动到我的表格底部

    forms - 如何防止从本地主机向服务器提交表单

    react-native - react-native中如何避免android键盘的建议

    amazon-web-services - 在 React-Native 中使用 AWS Amplify 显示来自 S3 的图像

    javascript - 将 POST 数据 react 到 ASP.Net

    node.js - 无法使用 npm 安装任何东西( react )

    android - 将它移动到另一台计算机后无法构建我的 android 项目