React native login, signup and navigation 风格二

创建react-native项目 ------ zigoo

myths-Mac:~ myth$ react-native init zigoo

myths-Mac:~ myth$ cd /Home/myth/zigoo && yarn add react-navigation

App.js 代码文件内容:

import React,{ Component } from 'react';
import {
AppRegistry,
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity
} from 'react-native';
import { StackNavigator } from 'react-navigation';

import HomeScreen from './src/components/Home';
import Login from './src/components/Login';
import Register from './src/components/Register';
import Profile from './src/components/Profile';

const MyApp = StackNavigator({
Home: { screen: HomeScreen },
Login: { screen: Login },
Register: {screen: Register},
Profile: {screen: Profile}

});
export default MyApp;

AppRegistry.registerComponent('MyApp',() => MyApp);

src/components/Home.js 代码文件内容:

import React,Text,
Button,
TouchableOpacity,
StatusBar,
Image
} from 'react-native';

export default class Home extends Component{
static navigationOptions= ({navigation}) =>({
title: 'Welcome',
});
render(){
const { navigate } = this.props.navigation;
return(
<View style={styles.container}>
<Text style={styles.pageName}>User Login</Text>
<TouchableOpacity
onPress={() => navigate('Login')}
style={styles.btn1}>
<Text style={styles.btnText}>Login</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={()=> navigate('Register')}
style={styles.btn2}>
<Text style={styles.btnText}>Register</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
display:'flex',alignItems:'center',
justifyContent:'center'
},
btn1:{
backgroundColor:'orange',
padding:10,margin:10,width:'95%'
},
btn2:{
backgroundColor:'blue',
pageName:{
margin:10,fontWeight:'bold',
color:'#000',textAlign:'center'
},
btnText:{
color:'#fff',fontWeight:'bold'
},

});

AppRegistry.registerComponent('Home',() => Home);

src/components/Register.js 代码文件内容:

import React,{ Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,Button,TextInput,TouchableOpacity
} from 'react-native';

export default class Register extends Component {
static navigationOptions= ({navigation}) =>({
title: 'Register',
headerRight:
<TouchableOpacity
onPress={() => navigation.navigate('Home')}
style={{margin:10,backgroundColor:'orange',padding:10}}>
<Text style={{color:'#ffffff'}}>Home</Text>
</TouchableOpacity>

});
constructor(props){
super(props)
this.state={
userName:'',
userEmail:'',
userPassword:''
}
}
userRegister = () =>{
const {userName} = this.state;
const {userEmail} = this.state;
const {userPassword} = this.state;
fetch('http://mo.com/register',{
method: 'POST',
headers:{
'Accept': 'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
name: userName,
email: userEmail,
password: userPassword,
})
})
.then((response) => response.json())
.then((responseJson) =>{
alert(responseJson);
})
.catch((error)=>{
console.error(error);
});
}

render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Enter Name"
style={{width:250,borderColor:"#333",
borderWidth:1}}
underlineColorAndroid="transparent"
onChangeText= {userName => this.setState({userName})}
/>
<TextInput
placeholder="Enter Email"
style={{width:250,borderWidth:1}}
underlineColorAndroid="transparent"
onChangeText= {userEmail => this.setState({userEmail})}
/>
<TextInput
placeholder="Enter Password"
style={{width:250,borderWidth:1}}
underlineColorAndroid="transparent"
onChangeText= {userPassword => this.setState({userPassword})}
/>
<TouchableOpacity
onPress={this.userRegister}
style={{width:200,padding:10,backgroundColor:'#3d6dcc',
alignItems:'center'}}>
<Text style={{color:'#fff'}}>Signup</Text>
</TouchableOpacity>
</View>

);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
});

AppRegistry.registerComponent('Register',() => Register);

src/components/Login.js 代码文件内容:

import React,TouchableOpacity,Keyboard
} from 'react-native';
import { StackNavigator } from 'react-navigation';

export default class Login extends Component {
static navigationOptions= ({navigation}) =>({
title: 'Login',
headerRight:
<TouchableOpacity
onPress={() => navigation.navigate('Home')}
style={{margin:12,padding:12}}>
<Text style={{color:'#ffffff'}}>Home</Text>
</TouchableOpacity>

});
constructor(props){
super(props)
this.state = {
userEmail:'',
userPassword:''
}
}

login = () => {
const { userEmail,userPassword } = this.state;
let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
if(userEmail == "") {
this.setState({email:'Please enter Email address'})
} else if(reg.test(userEmail) === false) {
this.setState({email:'Email is incorrect'})
return false;
} else if(userPassword=="") {
this.setState({email:'Please enter Password'})
} else {
fetch('http://mo.com/login',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ email: userEmail,password: userPassword })
})
.then((response) => response.json())
.then((responseJson) => {
if(responseJson == "ok"){
// redirect to profile page
alert("Login successfully");
this.props.navigation.navigate("Profile");
}else{
alert("Login failed");
}
})
.catch((error) => {
console.error(error);
});
}
Keyboard.dismiss();
}

render() {
return (
<View style={styles.container}>
<Text style={{padding:10,color:'red'}}>{this.state.email}</Text>
<TextInput
placeholder="Enter Email"
style={{width:250,borderWidth:1}}
underlineColorAndroid="transparent"
onChangeText={userEmail => this.setState({userEmail})}
/>
<TextInput
placeholder="Enter Password"
style={{width:250,borderWidth:1}}
underlineColorAndroid="transparent"
onChangeText={userPassword => this.setState({userPassword})}
/>
<TouchableOpacity
onPress={this.login}
style={{width:200,alignItems:'center'}}>
<Text style={{color:'white'}}>Login</Text>
</TouchableOpacity>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,

});

AppRegistry.registerComponent('Login',() => Login);

src/components/Profile.js 代码文件内容:

import React,{ Component } from 'react';
import { AppRegistry,View,StyleSheet } from 'react-native';

export default class Profile extends Component{
static navigationOptions= ({navigation}) =>({
title: 'Welcome',
});
render(){
const { navigate } = this.props.navigation;
return(
<View style={styles.container}>
<Text style={styles.pageName}>Profile</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
display:'flex',
});

AppRegistry.registerComponent('Profile',() => Profile);

单向数字证书
[root@contoso ~]# openssl genrsa -out ca-app.key 2048 ## 1). 生成一个CA私钥
Generating RSA private key,2048 bit long modulus
.......................................................................................................................................................+++
..........+++
e is 65537 (0x10001)
[root@contoso ~]# openssl req -x509 -new -nodes -key ca-app.key -days 365 -out ca-app.crt ## 2).使用ca-app私钥生成客户端的数字证书
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.',the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GuangDong
Locality Name (eg,city) [Default City]:ShenZhen
Organization Name (eg,company) [Default Company Ltd]:ZiGoo
Organizational Unit Name (eg,section) []: ## 直接按回车键跳过
Common Name (eg,your name or your server's hostname) []:mo.com
Email Address []:zhengzizhi@126.com
[root@contoso ~]# cp ca-app.key /etc/pki/tls/private/
[root@contoso ~]# cp ca-app.crt /etc/pki/tls/certs/
私钥文件 ca-app.key
数字证书 ca-app.crt


直接在httpd.conf配置文件查看apache执行用户和执行组,在以下红色字体标识的66行和67行即是用户和用户组,我们要把第66行和第67行改成如下的样子,其中myth是我登录CentOS 7.2系统的用户名

[myth@contoso ~]$ cat -n /etc/httpd/conf/httpd.conf #用此行命令查看httpd.conf文件的内容,注意我们要编辑的66和67行

第66行 User myth

第67行 Group myth


配置Apache服务器:

[myth@contoso ~]$ cat > /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.123.198 mo.com


[myth@contoso ~]$ cat > /etc/httpd/conf.d/httpd-vhosts.conf

<Directory "/home/myth/www/moapp">
Options +Indexes +FollowSymLinks
Order allow,deny
Allow from all
AllowOverride All
Require all granted
</Directory>
<VirtualHost *:80>
ServerAdmin zhengzizhi@126.com
DocumentRoot "/home/myth/www/moapp/public"
ServerName mo.com
ServerAlias mo.com
ErrorLog "/home/myth/log/httpd/mo-com-error_log"
CustomLog "/home/myth/log/httpd/mo-com-access_log" common
</VirtualHost>
<Directory "/home/myth/www/moapp">
Options +Indexes +FollowSymLinks
Order allow,deny
Allow from all
AllowOverride All
Require all granted
</Directory>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/ca-app.crt
SSLCertificateKeyFile /etc/pki/tls/private/ca-app.key
# SSLCertificateChainFile /etc/pki/tls/certs/ca-app.pem
ServerAdmin zhengzizhi@126.com
DocumentRoot "/home/myth/www/moapp/public"
ServerName mo.com
ServerAlias mo.com
ErrorLog "/home/myth/log/httpd/mo-com-s-error_log"
CustomLog "/home/myth/log/httpd/mo-com-s-access_log" common
</VirtualHost>

[myth@contoso ~]$ su -
Password:
Last login: Mon Apr 2 14:11:31 CST 2018 on pts/1
[root@contoso ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 1069 root 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 1315 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 1316 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 1317 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 1318 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 1319 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 2860 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 18468 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
httpd 18688 myth 4u IPv6 23009 0t0 TCP *:http (LISTEN)
[root@contoso ~]# systemctl restart httpd && systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2018-04-03 23:44:21 CST; 13ms ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 47406 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited,status=0/SUCCESS)
Main PID: 47415 (httpd)
Status: "Processing requests..."
CGroup: /system.slice/httpd.service
├─47415 /usr/sbin/httpd -DFOREGROUND
├─47416 /usr/sbin/httpd -DFOREGROUND
├─47417 /usr/sbin/httpd -DFOREGROUND
├─47419 /usr/sbin/httpd -DFOREGROUND
├─47420 /usr/sbin/httpd -DFOREGROUND
└─47421 /usr/sbin/httpd -DFOREGROUND

Apr 03 23:44:21 contoso.org systemd[1]: Starting The Apache HTTP Server...

Apr 03 23:44:21 contoso.org systemd[1]: Started The Apache HTTP Server.


配置macOS系统的hosts文件 ------ macOS这台机器是react-native这台开发机器

myths-Mac:~ myth$ sudo su

Password:
sh-3.2# cat > /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
192.168.123.198 mo.com


接下来我们要在macOS系统的命令行终端里通过命令去修改Android手机模拟器它的操作系统对应的hosts文件,修改它就有点特别啦,请按我的顺序执行指令,注意可能你的设备名称显示出来跟我的不一样,你需要开启两个终端窗口,一个用来首先用来启动安卓模拟用的,另外一个用来修改hosts文件用的,请特别注意192.168.123.198这个IP改成你实际的IP地址,本范例是在VMWare workstation pro 12 中实验的 1台PHP部署环境 用的系统是CentOS 7.2 另外一台开发react-native的机器是macOS系统

如果你已经有安卓模拟打开了 就必须关闭它们,那我们先来用命令以可写信息的模式来启动安卓模拟器吧:

电脑macOS系统中的命令终端窗口1,你发现自己emulator命令不是全局目录命令,

请参考我其它篇幅中讲的1条指令搞定配置部分

myths-Mac:~ emulator -list-avds #列出所有模拟器

Nexus_5X_API_23

myths-Mac:~ emulator -avd Nexus_5X_API_23 -writable-system #以可写信息的模式来启动安卓模拟器

电脑macOS系统中的命令终端窗口2,开始修改手机的hosts文件

myths-Mac:~ myth$ adb shell cat /etc/hosts

127.0.0.1 localhost
::1 ip6-localhost
myths-Mac:~ myth$ adb root
adbd is already running as root
myths-Mac:~ myth$ adb remount
remount succeeded
myths-Mac:~ myth$ adb pull /system/etc/hosts ~/Desktop/hosts
/system/etc/hosts: 1 file pulled. 0.0 MB/s (56 bytes in 0.003s)
myths-Mac:~ myth$ echo '192.168.123.198 mo.com' >> ~/Desktop/hosts
myths-Mac:~ myth$ cat ~/Desktop/hosts
127.0.0.1 localhost
::1 ip6-localhost

192.168.123.198 mo.com
myths-Mac:~ myth$ adb push ~/Desktop/hosts /system/etc/hosts
/Users/myth/Desktop/hosts: 1 file pushed. 0.0 MB/s (81 bytes in 0.005s)
myths-Mac:~ myth$ adb shell cat /etc/hosts
127.0.0.1 localhost
::1 ip6-localhost

192.168.123.198 mo.com

myths-Mac:~ myth$

[root@contoso ~]# exit #如果你的命令是root用户模式,请一定要退出root模式
logout
[myth@contoso ~]$

创建基于ThinkPHP 5.1 框架PHP项目 ------ moapp,退出root账户的命令模式环境安装框架并创建moapp项目:

[myth@contoso ~]$ cd /home/myth/www && composer create-project topthink/think moapp --prefer-dist

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`password` varchar(36) DEFAULT NULL,
`mobile` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

配置路由:

/home/myth/www/moapp/route/route.php

<?php
Route::post('login','index/Login/signin'); // POST http://mo.com/login
Route::post('register','index/Register/signup'); // POST http://mo.com/register
return [
];

实现控制器方法:

/home/myth/www/moapp/application/index/controller/Register.php

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Db;

class Register extends Controller {
public function signup(Request $request) {
$name = $request->param('name');
$email = $request->param('email');
$password = md5($request->param('password'));
$user = ['name' => $name,'email' => $email,'password' => $password];
// 启动事务
Db::startTrans();
try {
$count = Db::name('users')->where(['email' => $email])->count('id');
if ($count == 0) {
Db::name('users')->insert($user);
}
// 提交事务
Db::commit();
if ($count == 0) {
return json('Registered Successfully');
} else {
return json('E-mail already exist');
}
} catch (Exception $ex) {
// 回滚事务
Db::rollback();
return json('signup failed');
}
}

}

/home/myth/www/moapp/application/index/controller/Login.php

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Db;

class Login extends Controller {
public function signin(Request $request) {
$email = $request->param('email');
$password = md5($request->param('password'));
// 启动事务
Db::startTrans();
try {
$count = Db::name('users')
->where(['email' => $email])
->where(['password' => $password])
->count('id');
// 提交事务
Db::commit();
if ($count == 0) {
return json('login failed');
} else {
return json('ok');
}
} catch (Exception $ex) {
// 回滚事务
Db::rollback();
return json('login failed');
}
}

}

补充强调:模拟器必须用以下方式启动,开发工具上的启动方式启动安卓模拟器会立刻闪退,一旦模拟器被删掉,配置的手机hosts文件就立即被删掉

myths-Mac:~ Nexus_5X_API_23

以此处显示的Nexus_5X_API_23是模拟器的实际名称,我们可以用它来启动模拟器,当你发现开发工具上的模拟器按钮无法启动模拟器时,必须删除这个模拟重新创建一个新的模拟即可启动了,当然安卓手机的hosts文件也就恢复到了默认值 ------ 你配置的IP到域名映射关系就不存在啦

myths-Mac:~ emulator -avd Nexus_5X_API_23 -writable-system #以可写信息的模式来启动安卓模拟器

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom