我刚刚开始使用react native构建应用,并在名为HomeScreen.js
的同一页面上创建了具有视图和登录功能的基本登录功能。但是我已经从网络上阅读了一篇文章,并告诉我最好从视图中分离逻辑代码,这些功能必须在单独的页面上,视图也必须在不同的页面上。请我帮忙怎么做
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image, ActivityIndicator, Alert} from 'react-native';
import {Icon, Header, Left, Content, Container, Form, Input, Item, Button, Label, Toast} from 'native-base'
import SettingsScreen from './SettingsScreen';
class HomeScreen extends Component{
constructor(props){
super(props)
this.state={
showLoader: false,
}
}
static navigationOptions={
header: null,
drawerIcon:(
<Image source={require('../assets/imgs/logo.jpg')}
style={{height:24, width:24}}/>
)
}
render() {
return (
<Container>
<Header>
<Left>
<Icon name="ios-menu" onPress={() =>
this.props.navigation.toggleDrawer()}/>
</Left>
</Header>
<Content style={{backgroundColor:'white'}}>
<Content style={{alignContent:"center", top:100}}>
{ <Image source={require('../assets/imgs/logo.jpg')}
style={{height:200, width:200, alignSelf:"center"}}/> }
<Form>
<Item stackedLabel>
<Label >
Username
</Label>
<Input onChangeText={(text=>this.setState({userName:text}))} autoCapitalize = 'none'/>
</Item>
<Item stackedLabel last>
<Label >
Password
</Label>
<Input onChangeText={(text=>this.setState({passWord:text}))} secureTextEntry={true} />
</Item>
<Content style={{padding:20}}>
<Button onPress={this.userLogin.bind(this)} iconRight block primary disabled={!this.state.userName} disabled={!this.state.passWord}>
<Icon name='arrow-forward' />
<Text style={{color:'white'}}>Login</Text>
</Button>
</Content>
<Content>
<ActivityIndicator style={{padding:5}}
animating={this.state.showLoader}
size="small"
/>
</Content>
</Form>
</Content>
</Content>
</Container>
);
}
userLogin(){
this.setState({showLoader: true});
fetch('http://api_endpoint.com/login.php',{
method: 'POST',
body :JSON.stringify({
username: this.state.userName,
password: this.state.passWord
})
}).then((response)=>{
return response.json()
}).then((response)=>{
console.log(JSON.stringify(response.message))
this.setState({showLoader: false})
if(response.message==='0'){
Toast.show({
text: "Wrong Username or Password",
buttonText: "Try Again",
type: "danger",
duration: 4000
})
}else{
this.props.navigation.push('Settings');
}
}).catch((error) => {
this.setState({showLoader: false})
Alert.alert(
'Error!',
'Connection Failed, Try again later',
[
{text: 'Ok'}
],
{ cancelable: false }
)
});
}
}
export default HomeScreen;
答案 0 :(得分:0)
您已经有了一个不错的开端。请参考Udemy或其他网站上提供的适当视频教程,以获取良好的开始。由于您的问题较为客观,因此我们无法在此处解释全部内容。获得有关redux的知识,因此您可以将逻辑转移到redux reducer和action。也请尝试了解功能组件,您可以在其中移动视图并使主组件变稀。
https://www.udemy.com/react-native-the-practical-guide/?start=0
您可以参加上述课程以获得更多知识。
答案 1 :(得分:0)
在这种情况下,很清楚哪个代码是视图的一部分,哪个代码正在执行AJAX逻辑。 userLogin
函数显然不是演示性的;您可以从10英尺远的地方看到该代码与上面的代码完全不同。
但是,它与应用程序的其余部分有点联系,因为它执行与UI相关的事情,例如显示Toast
和导航。
分离此代码的一种方法是将函数分为两部分。将AJAX调用移至另一个(非React)文件,并删除与React相关的所有内容。它只会异步返回结果。然后,视图中代码的其余部分可以相应地响应(例如,显示Toast,导航或调用setState)。
下一步可能是将函数的其余部分移到容器组件中。该组件将提供登录功能,并将其结果存储在其自己的状态中。然后它将这些结果的相关部分传递到HomeScreen组件中。像这样:
import HomeScreen from './homeScreen';
import loginUser from '../apiClient';
class HomeScreenContainer extends Component {
doLogin = () => {
this.setState({loginInFlight: true});
loginUser(userName, password)
.then(result=>
this.setState({loginInFlight: false, loginResult: result});
if (result.loginSucceeded) {
this.props.navigation.push('Settings');
}
}).catch((error) => {
this.setState({showLoader: false, loginError: true})
});
}
render() {
return (
<HomeScreen
loginFunction={this.doLogin}
showLoader={this.state.loginInFlight}
shouldShowToast={this.state.loginResult.invalidLogin}
shouldShowError={this.state.loginError}
/>
)
}