React+RN开发过程中的一些问题总结(持续更新。。。)
amandakelake opened this issue · 15 comments
写RN的过程中踩过大大小小的坑,有些解决了,有些还等挖掘更好的方案,甚至有些解决不了的就直接绕道了(希望有大神指导一下),也一并记录下来好了,这部分也会持续更新。。。
可惜有些问题解决完就忘了,没记录下来,特别是调试、真机、平台方面的
题外话:有些当初苦苦想破脑袋的坑,踩过后才发现是如此的弱🐔,本来是不应该show出来贻笑大方的,但万一就是有小白也刚好陷入跟我当初一样的思维怪圈呢?所以不怕大家笑话,就一股脑都写下来吧,若干年后回头一看:原来当年我傻的如此可爱,能博得自己一笑,不也挺有意思的么
一、如何解决问题
这里科普一下自己遇到问题的通用解决办法
1、看官方文档,很多问题官方都已经考虑到了,对着关键词搜
这里要吐槽一句,RN的中文文档是真滴烂,推荐看英文文档(看不懂就好好学英语)
2、google (不要百度)
google出来的列表里面,优先看github的issue,其次看stackoverflow,然后才是其他的选项
3、问同事(一定要再自己google后),问你认识的大神好友
带着清晰的问题,**问题就别问了
4、以上三板斧都解决不了的话,信佛的阿弥陀佛,信基督的阿门吧
二、问题记录
PS:下面的问题全都没有按照顺序或者时间分类,大部分是以前自己随手记录的笔记,就是辛苦一些看文章的小伙伴了,或者可以cmd+F
或者ctrl+F
直接搜索自己需要的内容
1、RN:子元素宽度问题、位置居中
RN默认使用flex布局,子元素不用设置宽度,会自动拉伸满容器
如果子元素想居中
除了使用父元素的alignItems: 'center'
还是可以使用子元素的alignSelf: 'center'
这样子的话子元素的宽度不再拉伸,会按照实际内容宽度,如下
export default class PopularizeHome extends Component<Props> {
render() {
return (
<View>
<View style={styles.childContainer}>
<Text>PopularizeHome</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
childContainer: {
// alignSelf: 'center',
backgroundColor: 'red'
},
});
2、RN:使用原生的Navigator
时隐藏TarBar底部导航栏
会有小bug,最好是用react-navigation或者react-native-navigation
3、RN:HTTP安全限制
iOS9 & iOS10 HTTP 不能正常使用的解决办法 - iOS前沿 - SegmentFault
4、React:swiper高度限制
swiper自带的的高度是属性控制,不是样式控制
可以在swiper外面套一层来控制高度
5、React:循环渲染时,onPress事件不需要再把item当做参数
6、fecth使用formData上传数据
7、TextInput右边的padding会超出屏幕
8、react-navigation的设置navigationOptions
里面读取state的数据和绑定方法
9、复用input[radio]组件时,ID必须唯一,否则会两个input[radio]之间造成串联,互相影响
10、RN:AsyncStorage
本地存储,setItems时要用string,不能用到其他类型
setAsyncStorageIsLaunched() {
AsyncStorage.setItem('HAS_LAUNCHED',true).then(() => {
console.log('第一次登录成功',this.getAsyncStorageIsLaunched());
});
}
11、RN: source.uri should not be an empty string
有可能后台真的没有返回图片链接,虽然不是红色错误,黄色warning也很烦,做好三元判断就好了
{card.bank_background ? <Image
style={styles.itemBgIcon}
resizeMode="contain"
source={{ uri: card.bank_background }}
/> : null}
12、对于一些依靠后台数据的地方,做好拿不到数据或者错误数据的准备,给一个默认值,防止报错
13、Raw text cannot be used outside of a tag. Not rendering string: ''
{card.status_name && (
<View style={styles.itemTopRight}>
<Text style={styles.itemTopRightText}>{card.status_name}</Text>
</View>
)}
try the !! trick to make sure you only use booleans
{!!card.status_name && (
<View style={styles.itemTopRight}>
<Text style={styles.itemTopRightText}>{card.status_name}</Text>
</View>
)}
Or use the ? : 三元运算符
{card.status_name ? (
<View style={styles.itemTopRight}>
<Text style={styles.itemTopRightText}>{card.status_name}</Text>
</View>
) : null}
14、React Native ListView 需触摸/滑动后才显示的问题,官方Issues:
// 需要在初始化 ListView 时添加以下参数配置
removeClippedSubviews={false}
15、ListView的问题
16、使用FlatList的注意事项
17、安卓的物理返回键盘(防止直接退出应用)
18、RN:0.44版本后,Navigator和BackAndroid组件都不存在了
从0.44版本开始,Navigator不再从‘react-native’中引入,而是需要
npm install react-native-deprecated-custom-components –save
并在代码中引入
import { Navigator } from 'react-native-deprecated-custom-components'
同样从0.44版本开始,BackAndroid
组件不在出现,而是用BackHandler
代替
19、在render函数中中循环修改state,导致最后栈溢出
20、开debug模式时load bundle 100% 卡住(未解决),关掉远程debugger就就OK,需要重启电脑解决
WebSocket connection to ‘ws://localhost:8081/debugger-proxy?role=debugger&name=Chrome’ failed: Invalid frame header · Issue #6627 · facebook/react-native · GitHub
React-Native Error: Connection to http://localhost:8081/debugger-proxy?role=client timed out - Stack Overflow
还没解决
RCTModuleData deadlock when running with debugger · Issue #11196 · facebook/react-native · GitHub
RCTBridge required dispatch_sync to load RCTDevLoadingView. This may lead to deadlocks · Issue #16376 · facebook/react-native · GitHub
具体什么情况我也不是很清楚,mac的话,重启电脑就好了(我试验了很多次)
- 首先需要设置IP和端口,默认端口是8081,手机(模拟器)和电脑在同一个网络中,查询电脑的IP地址。
- 手动去删除
.babelrc
隐藏文件,具体文件目录为node_modules/react-deep-force-update/.babelrc
- 如果是其他版本,那也是需要删除的不过路径已经发生变化了。具体路径:
/node_modules/react-native/node_modules/react-transform-hmr/node_modules/react-proxy/node_modules/react-deep-force-update
- 最后重点 Android项目关闭终端重新执行运行命令,iOS项目也需要关闭服务终端,重新启动packager
21、子组件有复杂的数据和操作,需要父组件触发更新,但不想提升到父组件
使用componentWillReceiveProps增加父组件的标志位,子组件检测到父组件传下来的该标志位的变化时,即可触发更新
componentWillReceiveProps(nextProps) {
if (nextProps.needUpdatePopularize !== this.props.needUpdatePopularize) {
this.onRequestData();
this.requestRank();
}
}
22、Task orphaned for request <NSMutableURLRequest: 0x1c4202170>
Unmount images while loading · Issue #12152 · facebook/react-native · GitHub
图片还没完全加载完成的过程中,就触发其他操作,比如页面跳转,这时候又需要unmount 图片,就会出现这些黄色warning
同理,FlatList如果有很多图片要渲染,上下拉刷新时也会出现这些情况
23、安卓打包错误
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:validateSigningRelease'.
> Keystore file /Users/macbookpro-luoguangcong/projects/newapp/android/app/my-release-key.keystore not found for signing config 'release'.
android/app
文件夹下面缺一个my-release-key.keystore
文件,去旧项目复制过来即可
24、打包realease包的时候报错 main.jsbundle does not exist. This must be a bug with + echo 'React Native
先打包debug版本 看看有没有JS代码错误
如果确认OK,再重新yarn一次
25、webview 监听页面变化(不是自己写的H5,没办法使用postMessage)
_onNavigationStateChange(webViewState) {
// console.log('webview ???', webViewState);
if (webViewState.url.indexOf('*****') >= 0) {
this.props.repaymentActions.repaymentSetCreditCardListNew();
this.props.navigator.pop();
}
}
26、传参问题 企图修改原型属性
One of the sources for assign has an enumerable key on the prototype chain. Are you trying to assign a prototype property? We don't allow it, as this is an edge case that we do not support. This error is a performance optimization and not spec compliant.
27、关闭弹窗后自动执行两次路由操作
点击弹出框Btn => 收起弹框 => 切换tab => push进其他页面
1、收起弹框、切换tab,easy
2、当前处于什么scene就切换什么scene
3、在切换后的“我的“页面通过componentWillReceiveProps
监听scene的变化,然后push到对应的组件去
28、App与webview(H5)通信
postMessage发送消息
sendMessage(data) {
this.webview.postMessage(data);
}
onMessage监听
<WebView
injectedJavaScript={ debug}
style={}
source={{ uri: *** }}
userAgent={'GuardianAppIOS/1.0.0 Webview'}
onMessage={this.handleMessage}
/>
// the react native postMessage has only 1 parameter while the default one has 2, so check the signature of the function
waitForBridge(option) {
if (window.postMessage.length !== 1) {
setTimeout(() => {
this.waitForBridge();
}, 200);
} else {
window.postMessage(
JSON.stringify(option)
);
}
}
通过观察者(发布-订阅)模式进行页面的跳转
先实例化一个事件发布器
import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter'
let emitter = new EventEmitter()
export default emitter
if (url.startsWith('http://') || url.startsWith('https://')) {
return emitter.emit('NAVIGATION_NAVIGATE_TO', 'WebView', url, extraData)
}
在navigator进行监听,以及销毁时的移除
// add eventlistener: navigate to
emitter.addListener('NAVIGATION_NAVIGATE_TO', (routeName, url, extraData) => {
this.props.dispatch(
NavigationActions.navigate({
routeName,
params: routeName === 'WebView' ? { url, ...extraData } : {},
})
)
})
componentWillUnmount() {
emitter.removeAllListeners()
}
29、配置schemes URL
React Native URL Scheme and Linking API - Johnson Su
非常棒的指引
30、切换App主题
1、替换整个app(理解为品牌)
将所有color、size、position相关属性抽离出来,放到一个公共文件commonStyles.js
,导出常量使用
该文件根据config.js
中的THEME
进行判断采用哪一套主题
如此,只需要修改THEME
即可,达到一键替换的作用
2、app换皮肤
新建一个BaseCommon.js页面,作为这四个页面的父类。在这个父类里面接收主题更改的通知,并更新自己的主题。这样一来,继承它的这四个页面就都会刷新自己
31、中间模态窗
大概思路:
1、第三个导航样式上采用区别对待,该tab本来在路由系统中对应了一个页面组件,现在设置为null,改写它的点击事件(其他四个按钮则是正常的切换tab事件),点击则出现全屏弹层
wrapper: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
backgroundColor: templateUsage.shouldUseTemplateDaily()
? '#191A22'
: 'rgba(40, 47, 51, 0.8)',
},
3、弹层上的路由设置
直接抛弃掉真正的路由系统,用状态来控制页面的隐藏和显示,假装是push进一个页面,其实只是由一个state状态来控制一个页面显示,一个页面隐藏而已
消失或者隐藏,也就是加个动画,然页面更自然
closePopularize() {
this.state.y.setValue(0);
Animated.timing(this.state.y, {
toValue: Dimensions.get('window').height,
duration: 200
}).start(this.props.popPopularize);
}
clearPopularize() {
this.state.y.setValue(0);
Animated.timing(this.state.y, {
toValue: Dimensions.get('window').height,
duration: 200
}).start(this.props.clearPopularize);
}
总结的很好,另外还有个坑,ios9.0和10版本SafeAreaView组件不支持,需要手动判断
@shx1545 噢 对,这个忘了写了 感谢大佬
@amandakelake react-native自带的SafeAreaView组件是不支持ios10及以下,如果要用了react-navigation,可以引入它里面的。
import {SafeAreaView} from 'react-navigation'
@shx1545 嗯嗯 对的
请问一下25有没有什么好的方案可以解决
@yezidd 不是已经写出来了么 监听页面url的变化
webview 里面 alert 没有反应 , 这个可以解决吗?
第21,生命周期中的componentWillReceiveProps 将要弃用了,使用�新的 getDerivedStateFromProps
您好,请问下,一个App唤醒另一个App并且传参 ,react-native 能做到吗??
@jim888666 你搜索一下Linking看看
22条在FlatList中的image未卸载bug 应该是已经修复了
安卓的字体偏大,在屏幕上总是会出现文字被挡住一点,这个该怎么搞
com.facebook.jni.CppException: Could not get BatchedBridge, make sure your bundle is packaged correctly
这个是什么原因?大佬
com.facebook.jni.CppException: Could not get BatchedBridge, make sure your bundle is packaged correctly
这个是什么原因?大佬