最近尤勋,在用React Native開發(fā),以下是一個登錄界面茵宪,在登錄界面用到的知識點(diǎn)現(xiàn)總結(jié)如下:
1.在登錄成功之后最冰,我將服務(wù)器返回的數(shù)據(jù)存儲在react-native-storage中,token和用戶名稀火、密碼分別保存在不同的key中
2.網(wǎng)絡(luò)請求使用的fetch并進(jìn)行了封裝
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);
});
}
// 跳轉(zhuǎn)到第二個頁面去
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的子元素占滿整個區(qū)域
keyboardDismissMode="on-drag" // 拖動界面輸入法退出
keyboardShouldPersistTaps={false} // 點(diǎn)擊輸入法以外的區(qū)域篇裁,輸入法退出 不加這兩句也可以實(shí)現(xiàn)點(diǎn)擊空白處收回鍵盤
scrollEnabled={false} // 當(dāng)值為false的時候,內(nèi)容不能滾動赡若,默認(rèn)值為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({})
};