react-native&android 之开发问题篇一

本文总结了React Native开发中常见的六个问题及解决方案,包括Manifest合并冲突、依赖库版本不匹配、导航属性传递失败、FlatList优化、Yoga Node错误及PropTypes使用不当等问题。
摘要由CSDN通过智能技术生成

react-native 开发过程中引入别人的react-native-x库,环境上会有某种不通过。
着实很忧愁,下面就以我遇到的问题排下名词;

MEET 壹

Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(26.1.0) from [com.android.support:exifinterface:26.1.0] AndroidManifest.xml:25:13-35
    is also present at [com.android.support:appcompat-v7:26.0.2] AndroidManifest.xml:28:13-35 value=(26.0.2).
    Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:23:9-25:38 to override.

该问题出现原因是,AndroidManifest.xml合并过程中,由于com.android.support:appcompat版本不同导致无法成功合并;
solution:一股脑的把所依赖的react-native-x库等影响因素全部搞一致,按照我的经验,也并不一定把所有的依赖库的都搞一致。但是更重要的是你要判断出上面报错针对的是哪一个依赖库的。注意:按照上面日志的版本要求做。因为在一些react-native库中在实现功能上,要求的版本较高;

如下

compileSdkVersion 26
buildToolsVersion "26.0.2"
compile 'com.android.support:appcompat-v7:26.1.0'

MEET 贰

这里写图片描述

Error:Could not find common.jar (android.arch.core:common:1.0.0).
Searched in the following locations:
    https://jcenter.bintray.com/android/arch/core/common/1.0.0/common-1.0.0.jar

该问题出现原因是, jcenter已经删掉了android.arch.core库,所以需要从 maven { url “https://maven.google.com” }中获取android.arch.core:common-1.1.0.jar
solution:在project工程根目录下add代码指令maven { url "https://maven.google.com" }
如下:

allprojects {
    repositories {
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        //解决问题:Error:Failed to resolve: android.arch.core:common:1.1.0
        maven { url "https://maven.google.com" }
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

MEET 叁

这里写图片描述

undefined is not an object (evaluating 'this.props.navigation.goBack')

这里出现的问题是,我从react-native首页面HomeScreen.js中点击某个按钮。通过

import {StackNavigator,NavigationActions} from 'react-navigation';

this.props.navigation.navigate("GoodsListScreen")命令进入到一个新的列表,在新的Component页面中引入了一个自定义的TitleBar,就是这样的

export default class GoodsListScreen extends Component {
...
render() {
        return (<View style={styles.container}>
            <TitleBar
                /** {...this.props} 加上这一行就对了*/ 
                title = "育婴"
                headerBar = {{backgroundColor:Colors.black}}
                statusBar = {{backgroundColor:Colors.black}}
            />
            ...
        </View>);
    }
}

点击返回按钮,想要返回到上一个页面,就报错了
该问题出现原因是,undefined is not an object。结合上面图片,说明this.props.navigation是null。也就是说,页面组件属性this.props没有传到子组件中。
solution: TitleBar 标签中添加属性 {…this.props},可在子组件解构赋值。


MEET 肆

这里写图片描述

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
大概意思:只能更新已装载或装载过的组件。侧面说明你在这样未装载的组件上调用setState、replaceState或forceUpdate是不行滴。

我是怎么编出这样的代码逻辑的:写了一个demo例子,在react-native版本0.51.0下。对组件FlatList实现下拉刷新和上拉加载更多。但是在快速滑动页面,直接就加载了n多个item数据,并且中间一大段是空白,然后下边很快提示了上面的警告!
然后也看到官网上也有这方面的简单提示:

为了优化内存占用同时保持滑动的流畅,列表内容会在屏幕外异步绘制。这意味着如果用户滑动的速度超过渲染的速度,则会先看到空白的内容。这是为了优化不得不作出的妥协,而我们也在设法持续改进。

solution: 对组件FlatList添加属性

                onEndReachedThreshold={0.1}
                initialNumToRender={3}
                getItemLayout={(data, index) => ({
                    length: 250, offset: (250 + 10) * index, index
                })}

onEndReachedThreshold滑动到距离底部距离0.1*item高度开始加载更多;
initialNumToRender首次进入渲染**3个**item;
getItemLayout避免动态测量内容尺寸的开销;
解决了问题。源码地址分支blog0706


MEET 伍

这里写图片描述

Cannot add child that doesn't have a YogaNode to a parent without a measure function.

//正确代码
render() {
        return (<View style={{flex: 1, backgroundColor: Colors.bg}}>
            <FlatList
                ref={(flatlist) => this.flatlist = flatlist}
                ListHeaderComponent={this._header}
                renderItem={this._renderItem}
                ItemSeparatorComponent={this.props.itemSeparator}
                data={this.state.dataSource}
                keyExtractor={this._keyExtractor}
                onRefresh={() => this.onRefresh()}
                refreshing={this.state.isRefresh}
                onEndReachedThreshold={10}
                onEndReached={
                    () => this.onLoadMore()
                }
            />
            <Toast ref='toast'/>
        </View>);
    }

solution:我的问题出现的就是<Toast ref='toast'/>直接放在了上面代码块中,它所在行的上一行的'/>'的后面导致。这样竟然也能搞出错误,当然,有的博客上说在render方法中一些注释也会导致这种问题!


MEET 陆

这里写图片描述

undefined is not an object (evaluating '_react2.PropTypes.string')

我的代码是这样的,然出现上面的错误

/**
 * 功能:自定义的样式Button按钮
 * Created by YJH on 2018/7/10.
 */
import React, { Component,PropTypes } from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';

export default class Button extends Component {
    static propTypes = {
        text: PropTypes.string.isRequired,
        onClick: PropTypes.func.isRequired,
    };

    render() {
        const { text, onClick } = this.props;
        return (
            <TouchableOpacity style={styles.Button}  onPress={onClick}>
                <Text>{text}
                </Text>
            </TouchableOpacity>
        )
    }
}

const styles = StyleSheet.create({
    Button: {
       ...
    }
});

该问题出现原因是,ReactNative的Framework升级到0.50.3后,使用上面的引入方式就不能使用了。
依照我的项目,正确的引入方式是,import PropTypes from '../../../../../node_modules/prop-types/';
solution: PropTypes这个属性移动到了依赖的node_modules中**,再正确引入即可;

RNPolymerPo 是一个基于 React Native 的生活类聚合实战项目,目前由于没有 MAC 设备,所以没有适配 iOS,感兴趣的可以自行适配 app 目录下相关 JS 代码即可。 获取代码与编译调试打包 如下所有步骤及说明均为 React Native Android 的 DIY,涉及命令均为 Ubuntu 环境,Windows 类推即可。 1. 获取代码及模块安装和签名配置 执行如下命令进行代码下载及模块安装: $ git clone https://github.com/yanbober/RNPolymerPo.git $ cd RNPolymerPo $ npm install //如果觉得慢可以先切换到国内 npm 镜像源再执行此命令 配置 Gradle 个人签名路径及属性: //1. 把你个人的签名 my-release-key.keystore 文件(不知道如何生成请自行搜索)放到 RNPolymerPo 工程的 android/app 文件夹下。 //2. 编辑工程的 gradle.properties 文件,添加如下的代码(注意把其中的****替换为你自己相应密码)。 MYAPP_RELEASE_STORE_FILE=my-release-key.keystore MYAPP_RELEASE_KEY_ALIAS=my-key-alias MYAPP_RELEASE_STORE_PASSWORD=***** MYAPP_RELEASE_KEY_PASSWORD=***** 2. 编译打包 APK 文件 编译生成在线快速调试 Debug 开发包,执行如下命令: $ adb reverse tcp:8081 tcp:8081 $ react-native start //开启本地 JS 服务 $ react-native run-android //新终端的 RNPolymerPo 目录下执行 编译生成 release 包,执行如下命令: $ cd android && ./gradlew assembleRelease 拓展规划 下一个版本准备做的事情: 兼容性处理; 夜间模式; 热修复及 PHP 服务端编写; 多语言切换等问题评估;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值