最近,在用React Native开发,以下是一个登录界面,在登录界面用到的知识点现总结如下:
1.在登录成功之后,我将服务器返回的数据存储在react-native-storage中,token和用户名、密码分别保存在不同的key中
2.网络请求使用的fetch并进行了封装
3.在输入帐号和密码时,键盘弹出会遮住输入框,这里我在View外放了一个ScrollView来处理(如果有好的方法可以告诉我一下...)
效果图:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
TouchableOpacity,
PixelRatio,
ScrollView,
View,
TextInput,
Alert
} from 'react-native';
import { fetchRequest, AUTH_ERR_MSG, ERR_MSG } from '../../lib/network/request';
import config from '../../config';
import Home from './Home';
import storage from '../../storage/storage';
import { initialSocket } from '../consultant/gifted-chat/ConsultSocket';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#03a9f4'
},
flex: {
flex: 2
},
buttonView: {
flex: 3
},
title: {
textAlign: 'center',
color: 'white',
fontSize: 25,
marginTop: 80,
fontWeight: 'bold'
},
inputView: {
padding: 5,
backgroundColor: '#fff'
},
lineBottom: {
borderBottomWidth: 5 / PixelRatio.get(),
borderColor: 'rgb(208,208,208)'
},
button: {
marginTop: 30,
marginLeft: 10,
marginRight: 10,
height: 44,
borderRadius: 2,
backgroundColor: 'rgb(255, 64, 129)',
justifyContent: 'center',
overflow: 'hidden'
},
buttonText: {
fontSize: 22,
textAlign: 'center',
color: 'white',
fontWeight: 'bold'
},
text: {
flex: 1,
lineHeight: 44,
fontSize: 18,
justifyContent: 'center',
textAlign: 'center',
fontWeight: 'bold'
},
view: {
flexDirection: 'row',
height: 44
},
textInputStyle: {
flex: 5,
marginRight: 10,
fontSize: 18,
marginTop: 4
},
lineTopBottom: {
borderBottomWidth: 3 / PixelRatio.get(),
borderColor: 'rgb(208,208,208)'
},
centering: {
alignItems: 'center',
justifyContent: 'center'
}
});
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
token: ''
};
}
//
componentWillMount() {
storage.load({
key: 'account'
}).then((ret) => {
if (ret !== null) {
this.setState({
username: ret.username ? ret.username : '',
password: ret.password ? ret.password : ''
});
}
}).catch((err) => {
console.log(err);
});
}
// 跳转到第二个页面去
onLoginSuccess = () => {
// socket 初始化
initialSocket(this.state.token);
const { navigator } = this.props;
if (navigator) {
navigator.replace({
name: 'Home',
component: Home
});
}
}
clickLoginBtn() {
// 判断密码是否为空
if (this.state.username === '' || this.state.password === '') {
Alert.alert('账号或密码不能为空');
return;
}
fetchRequest(`${config.apiPrefix}/auth/consultant`, {
method: 'POST',
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
}, false).then((json) => {
if (json.retCode === 0) {
// 保存token
this.setState({
token: json.data.token
});
storage.save({
key: 'identity',
rawData: {
token: json.data.token,
headImg: json.data.userProfile.headImg,
userType: json.data.userProfile.userType,
name: json.data.userProfile.name
},
expires: json.data.ttl
}).then(() => {
// 保存account信息
storage.save({
key: 'account',
rawData: {
username: this.state.username,
password: this.state.password,
isAutoLogin: true
}
});
}).then(() => {
// 登录成功
this.onLoginSuccess();
})
.catch((err) => {
console.log(err);
throw new Error();
});
} else if (json.retCode === -2) {
// 用户名或密码错误
global.alert('账号或密码不能为空');
} else if (json.retCode === 5001) {
Alert.alert('账号或密码错误');
} else {
throw new Error();
}
}).catch((err) => {
if (err.message !== AUTH_ERR_MSG) {
// 出错的处理逻辑
Alert.alert(ERR_MSG);
console.error(err);
} else {
console.log(err);
}
});
}
render() {
return (
<ScrollView
contentContainerStyle={{ flex: 1 }} // 非常重要,让ScrollView的子元素占满整个区域
keyboardDismissMode="on-drag" // 拖动界面输入法退出
keyboardShouldPersistTaps={false} // 点击输入法以外的区域,输入法退出 不加这两句也可以实现点击空白处收回键盘
scrollEnabled={false} // 当值为false的时候,内容不能滚动,默认值为true
>
<View
style={styles.container}
>
<View style={styles.flex}>
<Text style={styles.title}>健康生活</Text>
</View>
<View style={styles.inputView}>
<View style={[styles.view, styles.lineTopBottom]}>
<Text style={styles.text}>账号:</Text>
<TextInput
style={styles.textInputStyle}
placeholder="请输入账号"
clearButtonMode="while-editing"
secureTextEntry={false}
onChangeText={(text) => {
this.setState({
username: text
});
}}
value={this.state.username}
/>
</View>
<View style={[styles.view, styles.lineTopBottom]}>
<Text style={styles.text}>密码:</Text>
<TextInput
style={styles.textInputStyle}
placeholder="请输入密码"
clearButtonMode="while-editing"
secureTextEntry
onChangeText={(text) => {
this.setState({
password: text
});
}}
value={this.state.password}
/>
</View>
</View>
<View style={styles.buttonView}>
<TouchableOpacity
style={styles.button}
onPress={() => this.clickLoginBtn()}
>
<Text style={styles.buttonText}>登 录</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
}
}
Login.propTypes = {
navigator: React.PropTypes.shape({})
};