在
react-native
中每个页面我们都会抽取一些小的组件,以便于维护和复用,那么组件间就免不了相互的数据传递,今天就记录下关于组件间消息传递的几种方法
父子组件间传值
由于是父子组件那么在父组件中可以很轻松的获取到子组件的实例。数据间传递还是很方便的。
在react-native
中 不需要想我们在写iOS
一样,需要先在子类中定义好属性,在传值 。在react-native
中每个组件都有一个props
属性。我们可以先设置属性数据,那么设置的这个属性数据,会自动保存在props
中。
- 我们先创建一个子组件
// 创建一个子组件
class Son extends Component {
render(){
return(
<View style={styles.sonStyle}>
<!-- 获取父组件中传递过来的数据 并显示 -->
<Text>我的名字叫{this.props.name}</Text>
</View>
)
}
}
- 创建一个父组件 在父组件中包含子组件
class Father extends Component {
render(){
return(
<View style={styles.fatherStyle}>
<!--添加子组件 并创建一个name属性 并赋值给Son组件 -->
<Son name= '小庄' ></Son>
</View>
)
}
}
现在Son
子组件已经可以获取到从父组件中传递的数据了,是不是 还挺简单的。那如果我们想从Son
组件传递数据给Father
应该怎么做呢
子组件传值给父组件(数据逆传)
我们想在父组件中获取到子组件传递过来的数据。首先我们也是通过props
来传参,但是这次我们传递的不是数据,而是类似于block
的函数作为参数传递给子组件。
- 首先我们先在父控件中定义好一个函数
// 实现方法接受子控件传达的值
getMoney(money) {
// 获取传过来的值,并赋值给自己的属性,刷新UI
// 获取之前的
var oldMoney = this.state.money
oldMoney += money
// 重新赋值
this.setState({
money: oldMoney
})
}
- 现在我们将定义好的函数赋值给子组件的属性。
render(){
return(
<View style={styles.fatherStyle}>
<Son name= '小庄' money={this.getMoney.bind(this)}></Son>
<Text>收到孩子的钱 + {this.state.money}</Text>
</View>
)
}
注: this.getMoney.bind(this) 这里使用
bind
来指定this
的指向关系,因为我们在getMoney
这个方法中需要使用到this
如果不做绑定的话,this
的指向关系有可能不对(this
可以理解为iOS
里的self
)
- 在子组件中获取属性,并调用。
class Son extends Component {
// 逆向传值
// 定义方法
sendMoney(){
// 获取props中报存的方法 并调用
this.props.money(100)
}
render(){
return(
<View style={styles.sonStyle}>
<Text>{this.props.name}的孩子</Text>
<Text onPress={this.sendMoney.bind(this)}>给爹发钱</Text>
</View>
)
}
}
至此在父控件中就可以收到子控件传递过来的100
数据了。
在开发中不仅仅有父子之间的数据传递,有时候也会涉及到,两个组件没有存在直接引用关系时的数据传递。在iOS
开发中我们一般会选用NSNotification
来处理这方面的逻辑。在react-native
中也提供了类似的API组件 也就是DeviceEventEmitter
它是包含在react-native
库中的,使用起来也比较方便,和iOS
的通知类似。
// 1 要使用DeviceEventEmitter 首先要导入
import
{
AppRegistry,
StyleSheet,
Text,
View,
DeviceEventEmitter
}
from 'react-native'
// 2 在需要传值的组件里,发送通知即可
// sendMoney 通知名称
// 100 传递的值
DeviceEventEmitter.emit('sendMoney',100)
// 3 在需要获取值的组件里 监听通知
// 'sendMoney' 通知名称
// this.getMoney.bind(this) 收到通知后 调用的方法
DeviceEventEmitter.addListener('sendMoney',this.getMoney.bind(this)) 实现方法
关于props
和State
这里说下我对props
和state
的理解;
首先props
和state
有一个共同点 就是他们都保存组件的属性。
不同点是:
- 从父组件中传递过来的属性数据都保存在
props
中,并且props
中的数据 只能在父控件中修改。修改props
也不会触发重新渲染。 - 而
state
是定义在组件内部,并且只有state
发生改变时(也就是调用setState
)才会重新渲染页面
或者更简单的理解为,外部传递过来的数据都保存在props
中,而组件内部创建的数据都保存在state
中。