React Native 組件間傳值

前言

本系列是基於React Native版本號0.44.3寫的。任何一款 App 都有界面之間數據傳遞的這個步驟的,那麼在RN中,組件間是怎麼傳值的呢?這篇文章將介紹到順傳、逆傳已經經過通知傳值。flex

  • 順傳

其實咱們在本系列第二篇文章中,講述Props和State的時候就已經接觸了順傳。this

經過props傳值code

舉個例子:父控件給子控件傳遞一個name屬性的值,子控件展現父控件傳遞過來的值:component

// 子組件
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。rem

// 子組件
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',
    },
});

逆傳

使用方法回調:it

在父組件定義一個處理接收值的方法
把這個方法傳遞給子組件,而且綁定this,子組件就能經過this.props拿到這個方法調用
舉個例子,一樣是點擊屏幕上的 + ,讓屏幕上的數字 加 1。(ps:和上面經過ref拿到子組件,傳遞的代碼有區別,注意組件層級)class

// 子組件
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生活費。List

// 弟弟組件
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',
    },
});

點擊發送生活費,就能夠看到弟弟能接收到生活費。方法

相關文章
相關標籤/搜索