React Native可以轻松实现跨平台,和原生开发相比,虽然语法变了,但是布局更灵活,以为开发会更简单,但是其实。。。现实很骨感。
思维难点一:面向对象的概念在这里不是很明显。属性可以不是由对象本身决定的,外部随便传入都可以,由外决定内。
思维难点二:任何的需要跳转的界面需要一开始去一个叫做路由(“router”)的地方去注册,然后在需要的时候靠相应的界面的字符串名称跳转。这个路由好比于字典,需要准确的Key值跳到具体的界面。好不容易习惯了字典转模型,现在又要退化回去了。
难点三:传值。
主要讲传值,遇到的坑,我会抽空来补齐。
1,界面间传值,参考上面难点二,在跳转的时候传值,跳转到相应的界面进行接收。
this.props.pushScreen('NA_Achievement', {
itemId : i,
activeName: this.props.activeName,
dateType: this.props.dateType
})
这里传输了三个值到命名为“NA_Achievement”的界面
然后在“NA_Achievement”界面里接收所传的值:
const {params} = this.props.navigation.state
// 选择了第几个
const chooseNumber = params ? params.itemId : -1
// 活动名称
const activeName = params ? params.activeName : '全部'
// 日期类型(0,当天 1,本周 2,本月)
const dateType = params ? params.dateType : '1'
需注意负责传值的界面默认的导出方法需要更改为:
export default connect(null, actions)(AchievementBottom)
需要在文件头导入
import * as actions from "../../src/actions"
import {connect} from "react-redux"
所谓actions和redux机制,以后搞明白了再谈。这思维难点之一。
2,父子组件之间的传值
这里的父子组件不是继承关系,只是整体和局部的关系。
正向传值
父组件传值给子组件容易,在子组件被调用的时候,父组件直接写属性即可,不用管子组件有没有既定的属性来接收。比如:
<AchievementTop
activeName = '端午大促活动'
pickerData = {['端午大促活动', '清明扫墓', '春节回家']}
/>
反向传值
子组件有操作变化了,需要传递回父组件,甚至需要传递给父组件的其它子组件,怎么办呢?
第一步,在父组件内新增传递子组件一个方法。以上例为例:
<AchievementTop
activeName = '端午大促活动'
pickerData = {['端午大促活动', '清明扫墓', '春节回家']}
pushDetails = {(dateType)=> this.changedDateType(dateType)}
/>
pushDetails = {(dateType)=>this.changedDateType(dateType)}中dateType即是准备接收子组件经过用户响应之后传递回来的值。获得子组件值后会执行changedDateType(dateType)方法:
changedDateType = (dateType)=>{
this.setState({
dateType: dateType
})
}
这就是改变了父组件值的状态!如果需要传递给其它的子组件,到这一步即可以参照上面正向传值了。
第二步,关键是在子组件里面做处理,响应了用户操作后如何传回?其实很简单
<TouchableHighlight underlayColor='transparent' onPress={() => {
this.setState({
chooseNumber: i
})
this.props.pushDetails(i)
}}>
<AchievementDate title={dateTitleArray[i]} isChoosed={this.state.chooseNumber===i}/>
</TouchableHighlight>
关键就是“this.props.pushDetails(i)”即可以了。
3,任意传值
参考我们原生开发中使用的观察者模式:通知、代理、block。React Native也提供了一个和通知相似的组件:DeviceEventEmitter
需要在文件头导入
import { DeviceEventEmitter } from 'react-native'
在获得用户响应的值之后写一行代码:
DeviceEventEmitter.emit('NotificationName_DateType', dateType)
在接收的组件的生命周期方法componentDidMount中接收
componentDidMount(){
DeviceEventEmitter.addListener('NotificationName_DateType', (dateType) =>{
this.setState({
dateType: dateType
})
})
}
这样完成了传值,最简单。不管中间界面多么复杂,两行代码搞定。
在原生开发中需注意的是一定要在完成传值之后移除这种通知,在RN中好像不需要。如果有需要了,我会及时补充更新。