前言
本系列是基於React Native
版本號0.44.3
寫的。任何一款 App 都有界面之間數據傳遞的這個步驟的,那么在RN
中,組件間是怎么傳值的呢?這篇文章將介紹到順傳、逆傳已經通過通知傳值。
順傳
其實我們在本系列第二篇文章中,講述Props
和State
的時候就已經接觸了順傳。
-
通過
props
傳值舉個🌰:父控件給子控件傳遞一個
name
屬性的值,子控件展示父控件傳遞過來的值:// 子組件 class SonComponent extends Component { render(){ return ( <View style={styles.sonViewStyle}> <Text style={{fontSize: 20}}>這是父視圖傳遞過來的數據:{this.props.name}</Text> </View> ); } } // 父組件 class FatherComponent extends Component { render(){ return ( <View style={styles.container}> <SonComponent name={this.props.name}/> </View> ); } } // 主組件 export default class RNDemoOne extends Component { render() { return ( <View style={styles.container}> <FatherComponent name="scott"/> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'red', }, sonViewStyle: { flex: 1, backgroundColor: '#F5FCFF', justifyContent: 'center', alignItems: 'center', }, });
上述代碼的數據傳遞其實是這樣的: 主組件 -> FatherComponent -> SonComponent。
但是有時候,我們並不是在創建 子組件 的時候就傳遞值,而是需要等待某個觸發事件的時候,再傳遞,這就涉及到獲取子組件傳值。 -
通過
ref
拿到組件,然后傳值舉個🌰:通過點擊屏幕上的 + 號按鈕,實現沒點擊一次,讓SonComponent的輸出數字加1。
// 子組件 class SonComponent extends Component { // 構造 constructor(props) { super(props); // 初始狀態 this.state = { number: 1 }; } addClick(number){ this.setState({ number: number }); } render(){ return ( <View style={styles.sonViewStyle}> <Text style={{fontSize: 20}}>{this.state.number}</Text> </View> ); } } // 父組件 class FatherComponent extends Component { render(){ return ( <View style={styles.container}> <SonComponent ref="son" number={this.props.number}/> <View style={styles.fatherViewStyle}> <Text style={{fontSize: 40}} onPress={() => { this.refs.son.addClick(this.refs.son.state.number + 1) }}>{"+"}</Text> </View> </View> ); } } // 主組件 export default class RNDemoOne extends Component { render() { return ( <View style={styles.container}> <FatherComponent number={1}/> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, }, sonViewStyle: { flex: 1, backgroundColor: '#F5FCFF', justifyContent: 'center', alignItems: 'center', }, fatherViewStyle: { flex: 1, justifyContent: 'center', alignItems:'center', }, });
逆傳
-
使用方法回調:
- 在父組件定義一個處理接收值的方法
- 把這個方法傳遞給子組件,並且綁定
this
,子組件就能通過this.props
拿到這個方法調用
舉個例子,同樣是點擊屏幕上的 + ,讓屏幕上的數字 加 1。(ps:和上面通過ref
拿到子組件,傳遞的代碼有區別,注意組件層級)
// 子組件
class SonComponent extends Component {
addClick(){
this.props.receiveNumber()
}
render(){
return (
<View style={styles.sonViewStyle}>
<Text style={{fontSize: 40}} onPress={this.addClick.bind(this)}>{"+"}</Text>
</View>
);
}
}
// 父組件
class FatherComponent extends Component {
// 構造
constructor(props) {
super(props);
// 初始狀態
this.state = {
number: 1
};
}
receiveNumber(){
var m = this.state.number;
m += 1;
this.setState({
number: m
});
}
render(){
return (
<View style={styles.container}>
<SonComponent receiveNumber={this.receiveNumber.bind(this)}/>
<View style={styles.fatherViewStyle}>
<Text style={{fontSize: 20}}>{this.state.number}</Text>
</View>
</View>
);
}
}
// 主組件
export default class RNDemoOne extends Component {
render() {
return (
<View style={styles.container}>
<FatherComponent/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
sonViewStyle: {
flex: 1,
backgroundColor: '#F5FCFF',
justifyContent: 'center',
alignItems: 'center',
},
fatherViewStyle: {
flex: 1,
justifyContent: 'center',
alignItems:'center',
},
});
通知
- 當兩個組件之間互相拿不到誰的時候,可以用通知傳值。比如當兩個組件是同一層級關系的時候(兄弟關系)。
舉個🌰: 點擊發送生活費,哥哥就給弟弟發送100生活費。
// 弟弟組件
class DiDiComponent extends Component {
// 構造
constructor(props) {
super(props);
// 初始狀態
this.state = {
money: 0
};
}
componentDidMount() {
// 添加監聽者
this.listener = DeviceEventEmitter.addListener('makeMoney', (money) => {
this.setState({
money: money
});
})
}
componentWillUnmount() {
// 銷毀監聽者
this.listener.remove();
}
render(){
return (
<View style={styles.didiStyle}>
<Text>弟弟</Text>
<Text>收到{this.state.money}零花錢</Text>
</View>
);
}
}
// 哥哥組件
class GeGeComponent extends Component {
render(){
return (
<View style={styles.gegeStyle}>
<Text>哥哥</Text>
<Text onPress={()=>{
DeviceEventEmitter.emit('makeMoney', 100)
}}>發生活費</Text>
</View>
);
}
}
// 主組件
export default class RNDemoOne extends Component {
render() {
return (
<View style={styles.container}>
<DiDiComponent/>
<GeGeComponent/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
didiStyle: {
flex: 1,
backgroundColor: '#F5FCFF',
justifyContent: 'center',
alignItems: 'center',
},
gegeStyle: {
flex: 1,
justifyContent: 'center',
alignItems:'center',
},
});
點擊發送生活費,就可以看到弟弟能接收到生活費。
好了,組件間傳值就講到這里了。
致謝
如果發現有錯誤的地方,歡迎各位指出,謝謝!