React Native 开发小Tips

图片描述

相信好多写React Native的都是前端出身,固然碰见问题的,也不少时候会想从前端出发,但因为React Native自己的限制,并非支持足够多的属性和样式,因此Bo主结合本身的开发实践,并总结了一些未来开发可能会碰见的问题并给出一些小的代码参考;(PS实现很差的但愿能你们提出见解,本身也会更新)。javascript

本身将代码放到了example下,而且作成了一个App.这样能够查看具体运行效果:html

截图1:前端

vuedf40e6bef8963252bd7eaa81f689e5c56.jpg

项目地址vue

开始

git clone https://github.com/JackPu/react-native-tips.git

进入example 目录java

react-native start

用xcode打开ios目录下的项目,运行就能够看到上面的运行界面了。react

1.关于按钮

写习惯了html咱们看到按钮,第一时间想到的即是Button,可是目前React Native并无这个组件,不过不要紧,咱们可使用 TouchableHighlight,TouchableOpacity来实现按钮组件,固然经常使用的样式能够应用在上面,造成格式各样的按钮。android

<TouchableHighlight onPress={this._onPressButton}>
      <Text>This is Button</Text>
</TouchableHighlight>

若是你实在很是喜欢按钮的话,不要紧,咱们引入已经封装好的组件react native buttonios

npm install react-native-button --save

安装好后,你就能够大胆的这样写了:git

<Button
    style={[Css.btn,Css.btnP]}
    styleDisabled={{color: 'red'}}
    onPress={() => this._handlePress()}>
    This is a button
  </Button>

2.文字过长隐藏的问题

CSS3中你们可能都会用到text-oveflow,然而RN 的Text并无这个属性,不过咱们能够经过设置numberOfLIne 或者JS自动计算来实现:github

<Text numberOfLines={1}>your long text here<Text>

3.关于百分比宽度

写样式的时候有的时候咱们常常会用到百分比,然而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,
    }
});

4.Grid列表

在App中的经常使用的列表除了水平列表外,咱们还须要栅格化的列表。好比相似于下面这样:

vuedcfb38c068d0c35a44b4bbc8a37ebeb10.png

作出相似的界面其实只要限制住你每个小方块的宽度就好了。

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>

详细代码

5.混合使用webview

不管何时,做为一个前端er,在遇到比较棘手的问题时候,咱们均可以回到原点,用一个网页去解决。所以不管如何都须要学会使用React Native webview。除此以外,部分页面,其实彻底能够由网页去支持多端共用的功能,楼主亲身遇到过的场景,就是图表的绘制,咱们的方案是一个页面,须要微信,手机网页,和android,ios都具有该功能,并且咱们手机网页和客户端打开的稍微有区别,须要隐藏header。

vuedc026487dfb0a62593d61ac2927fa727c.png

上图是网页版本的,而咱们经过设置页面的查询参数即来自客户端的请求或者微信的都会设置为相似这样的url

https://xxx.yoursites.com/page.html?hide_header=1&client=ios

vueda93127c21932b45b981c0d785f7c284f.png

而在React Native 设置webview 的代码也很简单,你能够查看这里代码

6.设置网络请求Fetch

因为客户端也须要大量接口的支持,所以咱们必定避免单兵做战,须要请求时候用个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);
    },

7.管理你的Icon

在网页中咱们常常能够看到很是多的小的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>
    );
}

vued9b724a613dd793d0e95400ff4e6884d7.png

8.构建一个导航条

固然制做App中,咱们常常会遇到制做导航条的要求,

vued191da6d8d8d42ea7d69a8cf3c287cb3f.png

你们可使用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

9.结合 Redux

想了想作个 App,有下面几个就能够了,界面不low, 数据支撑,用户响应便可。可是咱们在作的时候Css和Html确实解决了Bo主不会写界面的问题,可是后面两个咋个办呢?因而乎官方推出了一个新的工具[Redux]()。
精炼一点就是Redux就是去去管理页面的状态(用户响应)及数据(接口数据相关)。Redux中强调了三点:

  • 单一数据源

  • State 是只读的

  • 使用纯函数来执行修改

并且Redux支持服务端,这样更加方便咱们在进行异步的远程数据获取的实现。

一个简单的使用Demo

10.合理的使用第三方插件

尽管React Native 正式发布的时间还不算很是长,可是npm上已经拥有了大量的第三方类库,所以咱们在遇到问题或者强调快速开发的时候咱们能够去第三方网react.parts站寻找更好的组件。本身以为经常使用的一些以下:

11.调试

除了开发外,咱们还但愿可以很好的调试咱们的App.默认的话,就像咱们调试咱们的web页面同样,咱们能够用经常使用的console.log,console.error,console.warn,因为支持chrome调试,咱们能够在控制台看到打印的数据。固然,咱们也能够真机调试,好比连上你的iPhone,须要注意的是:

你须要修改调试js的地址,在AppDelegate.m中将"localhost"改为你电脑的ip就能够了。

选中你的iPhone就能够调试了。

固然我会持续更新,也欢迎你们pr,项目地址

vuedf40e6bef8963252bd7eaa81f689e5c56.jpg
最后安利一个ppt https://yunpan.cn/cqKEvrPXAS3gy (提取码:0375)


同步博客地址:http://www.jackpu.com/react-n...

相关文章
相关标签/搜索