怎么开场对我来说一个是个很纠结的问题,Emmm这应该算个好开场。
最近在做一个RN的app端调试工具,在把它嵌入原生app中的时候遇到了一个问题,RN组件里面接受不到原生传过来的initialProps?!
先po一下问题原因和答案,看官们有兴趣的话可以再看看下面的废话。
问题原因:首先看下我们一般怎么写,
const AppWithDebug = createStackNavigator({
Home: {
screen: App
},
...debugRoute
});
AppRegistry.registerComponent(appName, () => AppWithDebug);
一般情况下,我们会把createStackNavigator生成的对象,作为AppRegistry.registerComponent的入口文件,这个时候react-navigation在接收到initialProps之后并不会向下传递,而是只向下传递自身的navigation对象内容因此这个时候我们在组件中就拿不到原生传过来的initialProps内容了。
解决方案:隔离入口,不再使用createStackNavigator的结果去作为AppRegistry.registerComponent的入口,如
const AppWithDebug = createStackNavigator({
Home: {
screen: App
},
...debugRoute
});
class AppEntry extends Component {
render() {
return <AppWithDebug screenProps={ this.props }/>
}
};
AppRegistry.registerComponent(appName, () => AppEntry);
react-navigation不再处于项目入口的位置,入口处由一个包含了导航组件的组件代替。此时我们在AppEntry组件中就可以直接通过this.props拿到initialProps的值了,再通过screenProps向下传递即可,AppWithDebug中可以通过this.props.screenProps获取initialProps的相关内容。
~~问题解决~~以下是爬坑过程~~
碰到这个问题第一反应,什么鬼?官方文档是这么介绍的啊,
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
moduleName: @"RNHighScores"
initialProperties:
@{
@"scores" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions: nil];
注:请忽略我的强行缩进,节省点大家横向拖动的时间
文档写的明明白白,难道我是个傻子?你传过来,我直接this.props.xxx,一点毛病没有啊,为啥拿不到?在去原生同学那里一看他们的demo获取正常。。。
这个时候就准备在自己的项目上开始各种骚操作尝试一下,但是没等我大展拳脚就发现自己可能掉进react-navigation的坑里了,因为最开始去获取initialProps的时候打印了一下this.props对象,发现只有navigation一个子属性,于是就把导航去掉试了一下发现initialProps的属性居然就蹦出来了,这个时候基本就可以确定问题出在react-navigation上了。
这个时候去react-navigation的github官网上查一下issue,就发现了这个
看样子楼主遇到了一样的问题,并且真的是一步一步的证明了react-navigation在这个上面的bug,但第一次看了一圈没找到答案,直到第二次才找到答案
看到这里,真的是恍然大悟,你应该也明白了吧~其实就是隔离入口
经常看到结论,会恍然大悟“哦 原来就这样啊 这么简单”。
其实很多时候答案并不复杂,我们所或缺的是思考问题的方法,之所以写答案下面的这些”废话“,也是最近特别烦躁,经常会被问题卡住并且变得更烦躁,想给自己提个醒,让自己静一静。
目前的开发工作,除非是原创性的工作,一般情况下你遇到的问题都是别人遇到过的,只要去找,可能会很长时间,但终归还是可以解决的,github的issue是个找答案的好地方,耐心寻找。
烦躁并不能解决问题,只会扰乱你的思路,所以不要被情绪左右你的理智。
~加油 你是最胖的~