我尝试使用两个输入字段LogIn按钮和忘记密码按钮实现简单的LoginScreen。屏幕之间的导航是在" react-navigation":#34; 1.0.0-beta.11"的帮助下实现的。因此,当我在登录屏幕上单击忘记密码然后返回登录屏幕然后单击任何输入字段 - TypeError:期望动态类型double',但是有typenull' (出现在参数索引0处为UiManager.dispatchViewManagerCommand构造参数)。 似乎findNodeHandle返回null。但是如何解决这个问题??
React Native版本:0.44 反应版本:16.0.0-alpha.6 平台:Android
LoginScreen渲染方法:
render() {
const passInputContainerStyle = this.state.passwordError === I18n.t('error.password.invalid')
? styles.inputContainerLarge : styles.inputContainer;
if (this.props.isLoggedIn) {
Keyboard.dismiss();
NavigationUtils.navigateTo(this.props.navigation, 'Settings');
}
let errorGuy = this.verifyInputFieldsErrors();
return (
<DismissKeyboardView style={styles.container}>
<View style={styles.mainContainer}>
<View style={styles.logoContainer}>
<Image
style={styles.logo}
source={images.logo} />
</View>
<View style={styles.inputContainer}>
<EditTextWithError
hint={I18n.t('hint.email')}
errorMsg={errorGuy.emailErrorMessage}
errorMsgVisibility={errorGuy.emailErrorVisibility}
keyboardType='email-address'
eyeVisibility={false}
eyeHidePassModeEnabled={false}
isNextMode={true}
nextRef={this.state.refNextInput}
onEndEditing={() => this.onEndEditingEmail()}
onTextChanged={(text) => this.onEmailTextChanged(text)} />
</View>
<View style={passInputContainerStyle}>
<EditTextWithError
hint={I18n.t('hint.password.common')}
errorMsg={errorGuy.passwordErrorMessage}
errorMsgVisibility={errorGuy.passwordErrorVisibility}
eyeVisibility={true}
eyeHidePassModeEnabled={true}
isNextMode={false}
ref={(input) => this.passInput = input}
onEndEditing={() => this.onEndEditingPassword()}
onTextChanged={(text) => this.onPasswordTextChanged(text)} />
</View>
<TouchableOpacity style={styles.btnContainer} onPress={() => this.onLogInPressed()}>
<Text style={styles.btnText}>{I18n.t('login.btnLogIn')}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.fupContainer} onPress={() => this.onForgotPasswordPressed()}>
<Text style={styles.fupText}>{I18n.t('login.forgotPass')}</Text>
</TouchableOpacity>
{this.renderFooter()}
</View>
</DismissKeyboardView>
);
}
EditTextWithError代码:
import React, { Component, PropTypes } from 'react';
import {
Text,
View,
TextInput,
Image,
TouchableHighlight
} from 'react-native';
import images from '../../config/images';
const styles = require('./styles').default;
export default class EditTextWithError extends Component {
state = {
hideInput: false
};
static propTypes = {
hint: PropTypes.string,
errorMsg: PropTypes.string,
errorMsgVisibility: PropTypes.bool,
keyboardType: PropTypes.any,
eyeVisibility: PropTypes.bool,
eyeHidePassModeEnabled: PropTypes.bool,
isNextMode: PropTypes.bool,
nextRef: PropTypes.any,
onTextChanged: PropTypes.func,
onEndEditing: PropTypes.func
};
static defaultProps = {
keyboardType: 'default',
errorMsgVisibility: false,
eyeVisibility: false,
eyeHidePassModeEnabled: false,
isNextMode: false,
onTextChanged: (smth) => { },
onEndEditing: () => { }
}
getFocus() {
this.editText.focus();
}
componentWillMount() {
this.state.hideInput = this.props.eyeHidePassModeEnabled;
}
render() {
const { hint, errorMsg, errorMsgVisibility, keyboardType, eyeVisibility, eyeHidePassModeEnabled, isNextMode, nextRef, onTextChanged, onEndEditing }
= this.props;
let icon = this.state.hideInput ? images.eye.on : images.eye.off;
const isErrored = errorMsgVisibility ? styles.errorBorder : styles.normalBorder;
let returnKeyType = isNextMode ? "next" : "go";
return (
<View style={styles.container}>
<TextInput style={[styles.input, isErrored]}
placeholder={hint}
underlineColorAndroid='transparent'
autoCorrect={false}
secureTextEntry={this.state.hideInput}
multiline={false}
keyboardType={keyboardType}
placeholderTextColor='rgb(153, 153, 153)'
returnKeyType={returnKeyType}
onSubmitEditing={() => isNextMode ? nextRef.getFocus() : {}}
onChangeText={(text) => onTextChanged(text)}
onEndEditing={() => onEndEditing()}
ref={(textEdit) => this.editText = textEdit} />
{
errorMsgVisibility &&
<Text style={styles.errorText}>{errorMsg}</Text>
}
{
eyeVisibility &&
<TouchableHighlight style={styles.eyeContainer} underlayColor='transparent'
onPress={() => this.setState({ hideInput: !this.state.hideInput })} >
<Image source={icon} style={styles.eye} />
</TouchableHighlight>
}
</View>
);
}
}
导航代码:
export const LoginStack = StackNavigator({
Splash: {
screen: SplashScreen,
navigationOptions: {
header: null,
}
},
Login: {
screen: LoginScreen,
navigationOptions: {
header: null,
}
},
forgotPass: {
screen: ForgotPasswordScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <BackIcon nav={navigation} />,
headerTitle: I18n.t('forgotPass.screenTitle'),
headerStyle: styles.toolbar,
headerTitleStyle: styles.toolbarTitle
}),
},
Settings: {
screen: SettingsScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <BackIcon nav={navigation} />,
headerTitle: I18n.t('settings.screenTitle'),
headerStyle: styles.toolbar,
headerTitleStyle: styles.toolbarTitle
}),
}
});
const BackIcon = ({ nav }) => (
<TouchableOpacity onPress={() => nav.goBack()} style={styles.backIconContainer}>
<Image source={images.backArrow} style={styles.backIcon} />
</TouchableOpacity>
);
import { NavigationActions } from 'react-navigation';
export default class NavigationUtils {
static navigateWithoutAnAbilityToGoBackTo(navigation, _routeName) {
const actionToDispatch = NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: _routeName })]
})
navigation.dispatch(actionToDispatch);
}
static navigateTo(navigation, _routeName) {
navigation.navigate(_routeName);
}
}