相信好多写React Native的都是前端出身,固然碰见问题的,也不少时候会想从前端出发,但因为React Native自己的限制,并非支持足够多的属性和样式,因此Bo主结合本身的开发实践,并总结了一些未来开发可能会碰见的问题并给出一些小的代码参考;(PS实现很差的但愿能你们提出见解,本身也会更新)。javascript
本身将代码放到了example
下,而且作成了一个App.这样能够查看具体运行效果:html
截图1:前端
项目地址vue
git clone https://github.com/JackPu/react-native-tips.git
进入example 目录java
react-native start
用xcode打开ios目录下的项目,运行就能够看到上面的运行界面了。react
写习惯了html咱们看到按钮,第一时间想到的即是Button,可是目前React Native并无这个组件,不过不要紧,咱们可使用 TouchableHighlight,TouchableOpacity来实现按钮组件,固然经常使用的样式能够应用在上面,造成格式各样的按钮。android
<TouchableHighlight onPress={this._onPressButton}> <Text>This is Button</Text> </TouchableHighlight>
若是你实在很是喜欢按钮的话,不要紧,咱们引入已经封装好的组件react native button
ios
npm install react-native-button --save
安装好后,你就能够大胆的这样写了:git
<Button style={[Css.btn,Css.btnP]} styleDisabled={{color: 'red'}} onPress={() => this._handlePress()}> This is a button </Button>
CSS3中你们可能都会用到text-oveflow
,然而RN 的Text并无这个属性,不过咱们能够经过设置numberOfLIne 或者JS自动计算来实现:github
<Text numberOfLines={1}>your long text here<Text>
写样式的时候有的时候咱们常常会用到百分比,然而React Native并不支持这样的单位,除了用Flex布局外,咱们能够经过另一个方式得到:Dimensions
。固然因为都是JS
所以咱们能够取巧,用JS计算下,好比30%,
var React = require('react-native'); var {Dimensions,StyleSheet,Component} = React; // 咱们可使用Dimensions 去获取窗口宽度 var fullWidth = Dimensions.get('window').width; let thirtyPercentiWidth = fullWidth * 0.3; // Your stylesheet var styles = StyleSheet.create({ .wrap{ width: thirtyPercentiWidth, } });
在App中的经常使用的列表除了水平列表外,咱们还须要栅格化的列表。好比相似于下面这样:
作出相似的界面其实只要限制住你每个小方块的宽度就好了。
var styles = StyleSheet.create({ list: { justifyContent: 'flex-start', flexDirection: 'row', flexWrap: 'wrap' }, row: { justifyContent: 'center', padding: 5, margin: 5, width: (Dimensions.get('window').width - 30) / 3, height: 100, backgroundColor: '#fff', alignItems: 'center', }, thumb: { width: 55, height: 55 }, text: { flex: 1, marginTop: 10, } }); // render row <TouchableHighlight onPress={() => this._pressRow(rowID,rowData)} underlayColor='rgba(0,0,0,0)'> <View> <View style={styles.row}> <Image style={styles.thumb} source={{uri: rowData['game_icon']}} /> <Text numberOfLines={1} style={styles.text}> {rowData['game_name']} </Text> </View> </View> </TouchableHighlight>
不管何时,做为一个前端er,在遇到比较棘手的问题时候,咱们均可以回到原点,用一个网页去解决。所以不管如何都须要学会使用React Native webview。除此以外,部分页面,其实彻底能够由网页去支持多端共用的功能,楼主亲身遇到过的场景,就是图表的绘制,咱们的方案是一个页面,须要微信,手机网页,和android,ios都具有该功能,并且咱们手机网页和客户端打开的稍微有区别,须要隐藏header。
上图是网页版本的,而咱们经过设置页面的查询参数即来自客户端的请求或者微信的都会设置为相似这样的url
https://xxx.yoursites.com/page.html?hide_header=1&client=ios
而在React Native 设置webview 的代码也很简单,你能够查看这里代码
因为客户端也须要大量接口的支持,所以咱们必定避免单兵做战,须要请求时候用个fetch
,这样其实很是不易控制数据的流入。建议在fetch上在封装一次,这样咱们就能够作更多的事情,好比作统一的错误提示,用户失效控制,统一设置接口请求的header,同时能够方便咱们进行调试,在chrome中查看具体的接口数据等。
send(url,options) { var isLogin = this.isLogin(); var self = this; var defaultOptions = { method: 'GET', error: function() { options.success({'errcode':501,'errstr':'系统繁忙,请稍候尝试'}); }, headers:{ 'Authorization': this.getAccessToken(), 'Accept': 'application/json', 'Content-Type': 'application/json', 'App': 'vanthink-ios-app' }, data:{ // prevent ajax cache if not set '_regq' : self.random() }, dataType:'json', success: function(result) {} }; var options = Object.assign({},defaultOptions,options); var httpMethod = options['method'].toLocaleUpperCase(); var full_url = ''; if(httpMethod === 'GET') { full_url = this.config.api + url + '?' + this.serialize(options.data); }else{ // handle some to 'POST' full_url = this.config.api + url; } if(this.config.debug) { console.log('HTTP has finished %c' + httpMethod + ': %chttp://' + full_url,'color:red;','color:blue;'); } options.url = full_url; var cb = options.success; // build body data if(options['method'] != 'GET') { options.body = JSON.stringify(options.data); } // todo support for https return fetch('http://' + options.url,options) .then((response) => response.json()) .then((res) => { self.config.debug && console.log(res); if(res.errcode == 101) { return self.doLogin(); } if(res.errcode != 0) { self.handeErrcode(res); } return cb(res,res.errcode==0); }) .catch((error) => { console.warn(error); }); }, handeErrcode: function(result) { // not login if(result.errcode == 123){ // your code to do return false; } return this.sendMessage(result.errstr); },
在网页中咱们常常能够看到很是多的小的icon,咱们习惯性的用Css Sprite 和 Icon Font或者 Svg去解决这些问题。移步到客户端,一样,咱们也有不少解决方案,可是有一点必需要明确,将icon放到同一个地方,方便管理。这里有不少第三方库选择:
若是本身写的话,能够写到一个组件中,经过设置一个基类,而后进行继承和导出。设置不一样的图标思路大概以下:
import React, { TouchableHighlight,View,Text, Image, StyleSheet, PropTypes } from 'react-native'; // 基本的样式 let styles = StyleSheet.create({ icon: { width: 21, height: 21, marginTop: 4, marginRight: 15, }, }); class Icons extends React.Component { constructor(props) { super(props); this.press = this.press.bind(this); } press() { if(typeof this.props.press == 'function') { this.props.press(); }else{ // TODO } } _renderIcon() { return ( <Image source={require('../images/baseicon.png')} style={styles.icon} /> ); } render() { return ( <TouchableHighlight underlayColor="transparent" onPress={this.press}> {this._renderIcon()} </TouchableHighlight> ); } } // 继承 class CloseIcon extends Icons { _renderIcon() { return ( <Image source={require('../images/Delete-48.png')} style={styles.icon} /> ); } } class SearchIcon extends Icons { _renderIcon() { return ( <Image source={require('../images/Search-50.png')} style={styles.icon} /> ); } } // 导出 module.exports = { CloseIcon, SearchIcon, };
而咱们则能够在页面中这样使用
import {CloseIcon,SearchIcon} from '../style/icon'; ... render() { return( //... some code <CloseIcon></CloseIcon> ); }
固然制做App中,咱们常常会遇到制做导航条的要求,
你们可使用react-native-navbar,本身写也很是简单,样式大体就这些:
navBar: { height: 44, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'stretch', backgroundColor:'#fff' }, customTitle: { position: 'absolute', left: 0, right: 0, bottom: 7, alignItems: 'center', }, navBarButtonContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'stretch', }, navBarButton: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, navBarButtonText: { fontSize: 17, letterSpacing: 0.5, }, navBarTitleContainer: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', }, navBarTitleText: { fontSize: 17, color: '#333', fontWeight: '500', }
用法以下:
<View style={[styles.navBar,{backgroundColor: '#9b59b6'}]}> <View style={styles.navBarTitleContainer}> <Text style={[styles.navBarTitleText,{color: '#fff'}]}>NavBar3</Text> </View> <View style={[styles.navBarButtonContainer,{marginLeft:8}]}> <TouchableOpacity style={styles.navBarButton}> <View> <CloseIcon></CloseIcon> </View> </TouchableOpacity> </View> <View style={[styles.navBarButtonContainer,{marginRight:8}]}> <TouchableOpacity style={styles.navBarButton}> <View> <Text style={[styles.navBarButtonText,{color: '#fff'}]}>Done</Text> </View> </TouchableOpacity> </View> </View>
须要注意,若是设置顶部导航条,记得还有状态栏的高度要算进去,通常设置都为22
想了想作个 App,有下面几个就能够了,界面不low, 数据支撑,用户响应便可。可是咱们在作的时候Css和Html确实解决了Bo主不会写界面的问题,可是后面两个咋个办呢?因而乎官方推出了一个新的工具[Redux]()。
精炼一点就是Redux就是去去管理页面的状态(用户响应)及数据(接口数据相关)。Redux中强调了三点:
单一数据源
State 是只读的
使用纯函数来执行修改
并且Redux支持服务端,这样更加方便咱们在进行异步的远程数据获取的实现。
尽管React Native 正式发布的时间还不算很是长,可是npm上已经拥有了大量的第三方类库,所以咱们在遇到问题或者强调快速开发的时候咱们能够去第三方网react.parts站寻找更好的组件。本身以为经常使用的一些以下:
react-native-search-bar
一款带有经常使用搜索框的组件
react-native-refreshable-listview 一款带有刷新列表组件
react-native-router-redux 一款路由和redux结合的插件,组件比较丰富
react-native-image-picker 一款选择图片的插件
autobind-decorator 省去每次都要声明eventHandle.bind(this)
除了开发外,咱们还但愿可以很好的调试咱们的App.默认的话,就像咱们调试咱们的web页面同样,咱们能够用经常使用的console.log
,console.error
,console.warn
,因为支持chrome调试,咱们能够在控制台看到打印的数据。固然,咱们也能够真机调试,好比连上你的iPhone,须要注意的是:
你须要修改调试js的地址,在
AppDelegate.m
中将"localhost"改为你电脑的ip就能够了。
选中你的iPhone就能够调试了。
固然我会持续更新,也欢迎你们pr,项目地址
最后安利一个ppt https://yunpan.cn/cqKEvrPXAS3gy (提取码:0375)