[英]separating container component from presentational component in react native
i just started building apps with react native and created a basic login function with the view and the login function on the same page called HomeScreen.js
. 我刚刚开始使用react native来构建应用程序,并在名为HomeScreen.js
的同一页面上使用视图和登录功能创建了基本的登录功能。 But i've read article from the web and i'm told its best to seperate the logic code from the view, that the functions must be on a seperate page and the views on a different page as well. 但是我已经从网络上阅读了文章,并告诉我最好从视图中分离逻辑代码,这些功能必须在单独的页面上,视图也必须在不同的页面上。 Please i'll need help on how to do that 请我在此方面需要帮助
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;
You have done a great start. 您的开端很棒。 Please refer to a proper video tutorial available in Udemy or other sites to get a excellent start. 请参考Udemy或其他网站上提供的适当视频教程,以获取良好的开始。 As your question is more objective, we cannot explain entire thing here. 由于您的问题较为客观,因此我们无法在此处解释全部内容。 Get the knowledge about redux, so you can move the logic to redux reducers and actions. 获得有关redux的知识,因此您可以将逻辑转移到redux reducer和action上。 Also try to get to know about functional components where you can move the views and make the main component lean. 还尝试了解功能性组件,您可以在其中移动视图并使主组件变得精简。
https://www.udemy.com/react-native-the-practical-guide/?start=0 https://www.udemy.com/react-native-the-practical-guide/?start=0
You can take the above course for better knowledge. 您可以参加上述课程以获得更多知识。
In this case it's very clear which code is part of the view, and which is doing AJAX logic. 在这种情况下,很清楚哪个代码是视图的一部分,哪个代码正在执行AJAX逻辑。 The userLogin
function is obviously not presentational; userLogin
函数显然不是演示性的; you can see from 10 feet away that the code is totally different-looking from the code above it. 您可以从10英尺远的地方看到该代码与上面的代码完全不同。
However, it's a little bit tied to the rest of the app since it does UI-related things like show a Toast
, and navigate. 但是,它与应用程序的其余部分有点联系,因为它执行与UI相关的事情,例如显示Toast
和导航。
One way to separate out this code would be to split the function in two. 分离此代码的一种方法是将函数分为两部分。 Move the AJAX call out to another (non-React) file, and remove anything related to React. 将AJAX调用移至另一个(非React)文件,并删除与React相关的所有内容。 It would just asynchronously return a result. 它只会异步返回结果。 Then the remaining part of the code in your view can respond accordingly (eg show a Toast, navigate, or call setState). 然后,视图中代码的其余部分可以做出相应的响应(例如,显示Toast,导航或调用setState)。
The next step might be to move the remaining bit of the function into a container component. 下一步可能是将函数的其余部分移到容器组件中。 That component would provide the login function, and store its results in its own state. 该组件将提供登录功能,并将其结果存储在其自己的状态中。 Then it would pass the relevant parts of those results into the HomeScreen component. 然后它将这些结果的相关部分传递到HomeScreen组件中。 Something like: 就像是:
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}
/>
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.