VjL*_*xmi 4 forms nested reactjs react-native 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};
Run Code Online (Sandbox Code Playgroud)
如果我将所有内容 <SignInForm> 直接粘贴到渲染方法,则一切正常。
Max*_*Max 11
您的SignInForm函数(它被视为 React 组件,因为它大写并称为 JSX)在您的SignInScreenC组件中声明。这意味着每次渲染都会创建新类型的 React 组件。
SignInScreenC首次渲染:创建SignInForm组件,实例化并渲染它SignInScreenC第二次渲染:创建另一个完全不同的 SignInForm组件,再次实例化它,有效地卸载旧组件SignInForm并SignInForm在其位置渲染新组件这是由于 React 处理渲染的方式:每当遇到不同类型的元素应该被渲染来代替旧元素时,旧元素将被卸载。为了做出反应,SignInForm当您不断创建新功能时,每个新功能都与前一个不同
解决方案:
SignInForm在外部创建单独的组件SignInScreenC并将所有必要的数据作为道具传递const SignInForm = () => return (...)use const renderSignInForm = () => return (...),并且在渲染时,而不是<SignInForm/>像{renderSignInForm()}. 这样它就不会被当作组件对待,也不会成为卸载的对象| 归档时间: |
|
| 查看次数: |
1828 次 |
| 最近记录: |