这个也是一个基础项目

地址如下https://github.com/ndlonghi/react-native-template-app



点击登陆跳转到首页



分析代码如

react-native-template-app/src/components/loading/index.js

loading效果

import React from 'react';
import {
ActivityIndicator,
Image,
StyleSheet,
View
} from 'react-native'; function Loading(props) { return (
<View
style={styles.container}
>
<Image
source={require('../../assets/imgs/logo.png')}
style={styles.logo}
/>
<ActivityIndicator/>
</View>
) } const styles = StyleSheet.create({
container: {},
logo: {}
}); export default Loading;
//app.js
import React, {Component} from 'react';
import {Provider} from 'react-redux';
import {PersistGate} from 'redux-persist/integration/react';
//redux
//loading
//跳转路由
import {store, persistor} from "./src/store";
import Loading from "./src/components/loading/index";
import RootNavigator from "./src/navigation/containers"; export default class App extends Component {
render() {
return (
<Provider
store={store}
>
<PersistGate
loading={<Loading/>}
persistor={persistor}
>
<RootNavigator/>
</PersistGate>
</Provider>
);
}
}

src/store.js

import {
applyMiddleware,
createStore
} from 'redux';
import {persistStore, persistReducer} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import {createReactNavigationReduxMiddleware} from 'react-navigation-redux-helpers'; import rootReducer from './reducers'; const persistConfig = {
key: 'root',
storage,
blacklist: ['navigation']
}; const persistedReducer = persistReducer(persistConfig, rootReducer); const navigationMiddleware = createReactNavigationReduxMiddleware(
'root',
state => state.navigation
); const store = createStore(
persistedReducer,
applyMiddleware(navigationMiddleware)
); const persistor = persistStore(store); export {store, persistor};

src/reducers/index.js

import {combineReducers} from 'redux';

import auth from "../services/auth/reducers";
import navigation from "../navigation/reducers"; export default combineReducers({
auth,
navigation
});

数据处理

src/services/api/index.js

import {Environments} from "../../environments/environments";
import type {Credentials} from "../../models/credentials";
import type {AuthObject} from "../../models/auth-object";
import type {ApiErrorResponse} from "../../models/api-error-response"; class Api { static getBackendConfig() {
return Environments[Environments.env].backend;
} handleError(error: any): ApiErrorResponse {
let errorResponse: ApiErrorResponse = {
error: error,
text: 'An error ocurred. Please try again later.'
};
return errorResponse;
} async get(url: string): any | ApiErrorResponse {
return fetch(url, {
method: 'GET'
})
.then((response) => {
return response.json();
})
.catch((error: any) => {
reject(this.handleError(error));
})
} async post(url: string, data: any): any | ApiErrorResponse {
return fetch(url, {
method: 'POST',
body: JSON.stringify(data)
})
.then((response) => {
return response.json();
})
.catch((error: any) => {
reject(this.handleError(error));
})
} async login(credentials: Credentials): Promise<AuthObject | ApiErrorResponse> {
//const query = await this.post(Api.getBackendConfig().url + Endpoints.LOGIN, credentials);
//const {data} = await query.json();
//return data;
// Simulate api call
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({token: 'sanoteru'});
}, 1000);
})
} } const Endpoints = {
LOGIN: ''
}; export default new Api();
//src/services/auth/actions/action-tyes.js
export const SET_AUTH = 'SET_AUTH';
export const REMOVE_AUTH = 'REMOVE_AUTH';
///src/services/auth/actions/index.js
import {
REMOVE_AUTH,
SET_AUTH
} from "./action-tyes";
import type {AuthObject} from "../../../models/auth-object"; export const setAuth = (authObject: AuthObject) => ({
type: SET_AUTH,
payload: {
authObject
}
}); export const removeAuth = () => ({
type: REMOVE_AUTH
});
//src/services/auth/reducers/index.js
import {
REMOVE_AUTH,
SET_AUTH
} from "../actions/action-tyes"; function auth(state = {}, action) {
switch (action.type) {
case SET_AUTH: {
return {
authObject: action.payload.authObject
}
}
case REMOVE_AUTH: {
return {
authObject: null
}
}
default: {
return state;
}
}
} export default auth;
//src/screens/loading.js
import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux'; import {navigateToHome, navigateToLogin} from "../navigation/actions/index";
import LoadingLayout from '../components/loading/index'; const mapStateToProps = state => {
return {
auth: state.auth
}
}; const mapDispatchToProps = dispatch => {
return bindActionCreators({navigateToLogin, navigateToHome}, dispatch);
}; class Loading extends Component { componentDidMount() {
this.redirect();
} redirect = () => {
if (this.props.auth.authObject) {
this.props.navigateToHome();
} else {
this.props.navigateToLogin();
}
}; render() {
return <LoadingLayout/>
} } export default connect(mapStateToProps, mapDispatchToProps)(Loading);
//src/screens/login.js
import React, {Component} from 'react';
import {
Button,
Image,
SafeAreaView,
StyleSheet,
TextInput,
View
} from 'react-native';
import {connect} from 'react-redux';
import {bindActionCreators} from "redux"; import {removeAuth, setAuth} from "../services/auth/actions/index";
import {navigateToHome} from "../navigation/actions/index";
import type {AuthObject} from "../models/auth-object";
import type {ApiErrorResponse} from "../models/api-error-response";
import Api from '../services/api/index'; const mapDispatchToProps = dispatch => {
return bindActionCreators({setAuth, removeAuth, navigateToHome}, dispatch);
}; class Login extends Component { handleSubmit = () => {
Api.login({
email: 'mobile@4rsoluciones.com',
password: 'aoeu'
})
.then((auth: AuthObject) => {
this.props.setAuth(auth);
this.props.navigateToHome();
})
.catch((error: ApiErrorResponse) => {
this.props.removeAuth();
})
}; render() {
return (
<SafeAreaView style={styles.container}>
<View>
<Image
source={require('../assets/imgs/logo.png')}
style={styles.logo}
/>
<TextInput
style={styles.input}
placeholder="Username"
placeholderTextColor="white"
/>
<TextInput
style={styles.input}
placeholder="Password"
placeholderTextColor="white"
secureTextEntry={true}
/>
<Button
onPress={this.handleSubmit}
title="Log in"
/>
</View>
</SafeAreaView>
)
} } const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
},
logo: {
width: 200,
height: 80,
resizeMode: 'contain',
marginBottom: 10,
},
input: {
marginBottom: 10,
width: 250,
height: 50,
paddingHorizontal: 10,
borderRadius: 5,
backgroundColor: '#838383',
color: 'white',
}
}); export default connect(null, mapDispatchToProps)(Login);

login引用的是这里的api

import {Environments} from "../../environments/environments";
import type {Credentials} from "../../models/credentials";
import type {AuthObject} from "../../models/auth-object";
import type {ApiErrorResponse} from "../../models/api-error-response"; class Api { static getBackendConfig() {
return Environments[Environments.env].backend;
} handleError(error: any): ApiErrorResponse {
let errorResponse: ApiErrorResponse = {
error: error,
text: 'An error ocurred. Please try again later.'
};
return errorResponse;
} async get(url: string): any | ApiErrorResponse {
return fetch(url, {
method: 'GET'
})
.then((response) => {
return response.json();
})
.catch((error: any) => {
reject(this.handleError(error));
})
} async post(url: string, data: any): any | ApiErrorResponse {
return fetch(url, {
method: 'POST',
body: JSON.stringify(data)
})
.then((response) => {
return response.json();
})
.catch((error: any) => {
reject(this.handleError(error));
})
} async login(credentials: Credentials): Promise<AuthObject | ApiErrorResponse> {
//const query = await this.post(Api.getBackendConfig().url + Endpoints.LOGIN, credentials);
//const {data} = await query.json();
//return data;
// Simulate api call
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({token: 'sanoteru'});
}, 1000);
})
} } const Endpoints = {
LOGIN: ''
}; export default new Api();
//src/screens/home.js
import React, {Component} from 'react';
import {
Button,
SafeAreaView,
StyleSheet,
Text,
View
} from 'react-native';
import {connect} from 'react-redux';
import {bindActionCreators} from "redux"; import {removeAuth} from "../services/auth/actions/index";
import {navigateToLogin} from "../navigation/actions/index"; const mapDispatchToProps = dispatch => {
return bindActionCreators({removeAuth, navigateToLogin}, dispatch);
}; class Home extends Component { handleLogout = () => {
this.props.removeAuth();
this.props.navigateToLogin();
}; render() {
return (
<SafeAreaView style={styles.container}>
<View>
<Text>This is the home</Text>
<Button
onPress={this.handleLogout}
title="Log out"
/>
</View>
</SafeAreaView>
)
} } const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
}
}); export default connect(null, mapDispatchToProps)(Home);

关于navigation部分还进行了很多处理,项目不容易啊~

最新文章

  1. Ubuntu ssh 服务
  2. mq_notify
  3. Helpers\Pagination
  4. Myeclipse中如何修改Tomcat的端口号
  5. 去掉ILDasm的SuppressIldasmAttribute限制
  6. 扔鸡蛋问题具体解释(Egg Dropping Puzzle)
  7. 小米2S TWRP 3.0.2-0 最新版Recovery
  8. chapter9_3 协同程序实现迭代器
  9. ACM心路
  10. 剑指offer 二叉搜索树后续遍历序列 判断
  11. Android WebKit 内核
  12. 北京大学Cousera学习笔记--7-计算导论与C语言基础--基本数据类型&amp;变量&amp;常量
  13. PHP保留两位小数并且四舍五入及不四舍五入的方法
  14. JDK自带观察者的使用
  15. pycharm如何回到过去某个时间
  16. MySQL的库、表详细操作
  17. Tomcat源码分析——类加载体系
  18. json对象与json字符串互转方法
  19. 在linux上配置Django项目
  20. chrome中,BackstopJS 使用cookie文件后依旧提示需要登录

热门文章

  1. IIS首次发布VS2012创建的web应用程序时注册.net4.0
  2. ArcSDE 10.0与ArcSDE10.1的又一个区别
  3. [转载] OpenCV2.4.3 CheatSheet学习(二)
  4. 《DSP using MATLAB》Problem 7.28
  5. 状态模式(State)(开关灯,状态实例为类,不同状态,不同行为)
  6. Jmeter运行原理
  7. css3之文本和颜色功能之text-shadow
  8. js 之观察者模式
  9. 在windows系统和linux系统中查询IP地址命令的不同
  10. Tarjan求LCA(离线)