简体   繁体   English

在React Native中将容器组件与表示组件分离

[英]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.

相关问题 React &amp; Redux - 展示组件中的容器组件? - React & Redux - container component inside a presentational component? 反应表示组件无法读取值 <input /> 来自redux商店使用反应容器 - React presentational component unable to read value for <input /> from redux store using react container Vue.js 中 React 容器和展示组件的等价物 - Equivalent of a React container and presentational component in Vue.js 获取TypeError:_red2.props.handleClick不是一个函数,当将redux prop从容器传递到react中的表示组件时 - Getting TypeError: _this2.props.handleClick is not a function when passing redux prop from container to presentational component in react Redux 展示组件与容器组件 - Redux Presentational Components Vs Container Component React / Redux:分离表示和容器组件的困境。 - React/Redux: separating presentational and container components dilemma. 终极版。 从容器组件描述表示组件的生命周期方法 - Redux. Describe presentational component's lifecycle methods from a container component 反应-从另一个组件的演示组件打开模式将不起作用。 为什么? - React - opening modal from presentational component from another component won't work. Why? 使用Redux时,将事件从表示形式传递到容器组件是否是反模式? - Is passing an event from a presentational to container component an anti-pattern when using Redux? 在react-redux演示文稿组件中使用动作存在问题 - Trouble using actions in react-redux presentational component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM