React Native 系列(五) -- 组件间传值

前言

本系列是基于React Native版本号0.44.3写的。任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传、逆传已经通过通知传值。

顺传

其实我们在本系列第二篇文章中,讲述PropsState的时候就已经接触了顺传。

  • 通过props传值 举个?:父控件给子控件传递一个name属性的值,子控件展示父控件传递过来的值:

上述代码的数据传递其实是这样的: 主组件 -> FatherComponent -> SonComponent。 但是有时候,我们并不是在创建 子组件 的时候就传递值,而是需要等待某个触发事件的时候,再传递,这就涉及到获取子组件传值。

  • 通过ref拿到组件,然后传值 举个?:通过点击屏幕上的 + 号按钮,实现没点击一次,让SonComponent的输出数字加1。

逆传

  • 使用方法回调:
  1. 在父组件定义一个处理接收值的方法
  2. 把这个方法传递给子组件,并且绑定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',
    },
});

点击发送生活费,就可以看到弟弟能接收到生活费。

好了,组件间传值就讲到这里了。

致谢

如果发现有错误的地方,欢迎各位指出,谢谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏全栈架构

看微信小程序 wx.canvasToTempFilePath 方法之巨坑的解决之道

当然这个项目是可以用的,但是生成不了图片,打开 tempFilePath直接报错,发现了什么原因了吗?

2781
来自专栏散尽浮华

Html之初体验

概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言。相当于定义统一的一套规则,大...

24010
来自专栏小程序之家

如何使用小程序表单组件

上一篇文章中,我们给大家介绍了小程序的视图容器及基础内容组件,该组件主要应用是输出内容。接下来这篇文章中,我们将继续介绍小程序最常用的表单组件,该组件主要应用是...

2533
来自专栏编程之旅

自定义UISearchController的外观

以前我们在项目中使用搜索框的时候,如果用系统自带的控件则是使用UISearchDisplayController,而自从iOS8之后,系统重新给我们提供了一个搜...

2052
来自专栏IMWeb前端团队

移动端重构实战系列2——line list

本文作者:IMWeb 结一 原文出处:IMWeb社区 未经同意,禁止转载 ”本系列教程为实战教程,是本人移动端重构经验及思想的一次总结,也是对sand...

2218
来自专栏BestSDK

年薪30万的前端面试题,你能答对几道?|附答案

HTML面试题 1.XHTML和HTML有什么区别 HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言 最主要的不同: XHTML 元...

4236
来自专栏IMWeb前端团队

React16中的服务端渲染(译)

本文作者:IMWeb zzbozheng 原文出处:IMWeb社区 未经同意,禁止转载 React 16发布了。 React 16有很多令人兴奋的新东...

8819
来自专栏Rindew的iOS技术分享

使iPhone也可以拥有iPad的pop效果

1904
来自专栏前端说吧

vue - v-model实现自定义样式の多选与单选

来不及研究为什么,我先直接在原来项目上赶紧建了一个test页面,先赶紧实现我的这种设想:

3911
来自专栏腾讯社交用户体验设计

高清ICON SVG解决方案(下) - 腾讯ISUX

1741

扫码关注云+社区

领取腾讯云代金券