React中组件通信01——props

2023-09-17 21:53:10

1. 父传子——props

1.1 简单例子——props

  • 给子组件标签添加属性,属性名自定义,保持语义化即可。
  • 简单例子的核心代码,很简单就先截图吧,代码一起附在最后了,需要注意的是:类式组件与函数式组件的不同,如下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 props 可以传递任何数据

1.2.1 传递数字、对象等

  • 上面我们看到传递的是字符串,下面简单看看传递对象,如下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2.2 传递函数

  • 这个详细看下面的 《2. 子传父 + 子传子》,下面有详细的介绍。

1.2.3 传递模版jsx

  • 如下:
    在这里插入图片描述
    在这里插入图片描述

2. 子传父 + 子传子——props

2.1 父传子——传递函数

  • 父传子函数的重要性,主要是下面怎么通过它实现子传父,简单看看父传子传函数,如下:
    在这里插入图片描述
  • 效果如下:
    在这里插入图片描述

2.2 子传父——通过父传子的函数实现

  • 下面需求是在,子组件里添加狗狗数据,并把数据传递给父组件,如下:
    在这里插入图片描述
  • 看效果:
    在这里插入图片描述

2.3 优化 + 子传子(兄弟通信)

  • 下面实现的需求是:在上面子组件D中有一个按钮,点击触发addDog(即:添加新的dog),并在另一个子组件E中有所体现。
  • 所以流程就是:父把函数addDog 传递给子组件D,子组件D中在调函数的时候把新增数据传给父,父的addDog中实现更新state数据,然后子组件E中实时展示最新的父中的传来的state数据,具体实现,如下:
    • parent.jx,如下:
      在这里插入图片描述
    • D组件如下:
      在这里插入图片描述
    • E组件中就简单了,直接接受父传来的数据即可,如下:
      在这里插入图片描述
  • 效果如下:
    在这里插入图片描述

3. render props

3.1 组件标签上的标签体内容 传递

  • 如果要传递组件标签上的标签体内容,获取的时候需要注意,此传递的内容放到了props的children属性上,如下:
    在这里插入图片描述
    在这里插入图片描述
  • 如果上面的标签体内容放的不是love,而是另外一个组件F,和ChildE形成父子关系的F组件,那依然是放在了props的children属性上,如下:
    在这里插入图片描述
    在这里插入图片描述

3.2 render props

  • 上面3.1中通过把组件F放在ChildE的标签体内来形成父子关系,可以用另外一种方式实现,就是通过传递箭头函数的方式,如下:
    在这里插入图片描述
    在这里插入图片描述
     <div className="childE">
         <ChildE dogList={this.state.dogList} 
                 testJsx={<p>测试一下传递jsx</p>}
                 render={()=><F/>}
                 />
     </div>
    
    {props.render()}
    
  • 传参数的情况,这里的函数名习惯用render,所以叫 render props ,如下:
    在这里插入图片描述
     <div className="childE">
         <ChildE dogList={this.state.dogList} 
                 testJsx={<p>测试一下传递jsx</p>}
                 // render={()=><F/>}
                 render={(kind)=><F petKind={kind}/>}
                 />
     </div>
    
    {props.render('狗狗')}
    
    接到E传来的宠物类型是:{props.petKind}
    

4. 附代码:

  • parent.jsx:
    import React from "react";
    import ChildA from "./ChildA";
    import ChildB from "./ChildB";
    import ChildC from "./ChildC";
    import ChildD from "./ChildD";
    import ChildE from "./ChildE";
    import F from "./F";
    import './index.css'
    
    class Parent extends React.Component{
        state = {
            notice:'通知——今天有学生被开除了!',
            expelledNum:1,
            student:{name:'张三',age:21,reason:'逃课次数过多'},
            citys:['北京','上海','广州','深圳'],
            dogList:[
                {dogName:'麦兜',dogAge:3},
                {dogName:'贝塔',dogAge:2},
            ]
        }
        //给子组件传递的函数
        getCityStrs =()=>{
            // console.log(this.state.citys);
            return this.state.citys;
        }
        //给子组件传递的带参数函数,参数用来接受子组件在调用函数时给父组件传递的数据
        addDog =(dog)=>{
            console.log('收到子组件添加的新dog:',dog);
    
            //更新 state中 dogList的数据,这样子组件E中展示的数据就是最新的
            const dogList = this.state.dogList; //获取旧数据
    
            const newDogList = [...dogList,dog]; 
            console.log(newDogList);
            this.setState({dogList:newDogList});// 更新state
        }
    
        render(){
            return(
                <div className="parent">
                    我是父组件!
                    <div className="childA">
                        <ChildA notice={'通知——今天放假!'}/>
                    </div>
                    <div className="childB">
                        <ChildB notice={this.state.notice} expelledNum={this.state.expelledNum} student={this.state.student}/>
                    </div>
                    <div className="childC">
                        <ChildC getCityStrs={this.getCityStrs}/>
                    </div>
                    <div className="childD">
                        <ChildD addDog={this.addDog}/>
                    </div>
    
                    <div className="childE">
                        <ChildE dogList={this.state.dogList} 
                                testJsx={<p>测试一下传递jsx</p>}
                                // render={()=><F/>}
                                render={(kind)=><F petKind={kind}/>}
                                />
                    </div>
                </div>
            )
        }
    }
    
    export default Parent;
    
  • xxxA.jsx
    import React from "react";
    
    class ChildA extends React.Component{
        render(){
            return(
                <div>
                    我是子组件A!!!——类式组件
                    <br /><br />
                    收到来自于父组件的数据:{this.props.notice}
                </div>
            )
        }
    }
    
    export default ChildA;
    
  • xxxB.jsx
    function ChildB(props){
        // console.log(props);
        const {name,age,reason} = props.student;
    
        return(
            <div>
                我是子组件B!!!——函数组件
    
                <br /><br />
                收到来自于父组件的数据:{props.notice}
                <br />
                被开除的人数是:{props.expelledNum}
                <br />
                被开除学生的信息:{name}-{age}-{reason}
    
            </div>
        )
    }
    
    export default ChildB;
    
  • xxxC.jsx
    function ChildC(props){
        // console.log(props);
    
        //调用父传过来的函数 获取citys数据
        const citys = props.getCityStrs();
        // console.log(citys);
    
        return(
            <div>
                我是子组件C!!!——函数组件
    
                <br /><br />
                收到父传子的函数,并调用函数获取了数据:
                {
                    citys.map((city,index)=>{
                        return <li key={index}>{city}</li>
                    })
                }
    
            </div>
        )
    }
    
    export default ChildC;
    
  • xxxD.jsx
    function ChildD(props){
        // console.log(props);
    
        const newDog = {dogName:'泡泡',dogAge:7};// 1. 准备要新增的dog数据
    
        const addDog = props.addDog;//2. 获取父组件传递过来的函数 addDog
        // addDog(newDog); //3. 在子组件中 执行 addDog 函数,并将新增dog传参过去给父组件
    
        return(
            <div>
                我是子组件D!!!——函数组件
    
                <br />
                {/* 1. 点击时,再把newDog 传过去   
                    2. 当然,这里如果看着不舒服,也可以把上面3步封装成一个函数,点击时触发新封装的函数 */}
                <button onClick={()=>addDog(newDog)}>添加狗狗</button>
            </div>
        )
    }
    
    export default ChildD;
    
  • xxxE.jsx
    function ChildE(props){
        console.log(props);
        const dogList = props.dogList;
        // console.log(dogList);
    
        return(
            <div>
                我是子组件E!!!——函数组件
                <br />
                {props.testJsx}
                <br />
    
                展示狗狗信息:
                <ul>
                    {dogList.map((dog,index)=><li key={index}>{dog.dogName}-{dog.dogAge}</li>)}
                </ul>
    
                <hr />
                {/* {props.children} */}
                {/* {props.render()} */}
                {props.render('狗狗')}
    
            </div>
        )
    }
    
    export default ChildE;
    
  • F.jsx
    function F(props){
    
        return(
            <div>
                我是E组件的子组件,我是F!!!——函数组件
                <br />
                接到E传来的宠物类型是:{props.petKind}
            </div>
        )
    }
    
    export default F;
    
更多推荐

开始在 Windows 上将 Python 用于 Web 开发

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录设置开发环境安装适用于Linux的Windows子系统设置VisualStudioCode创建新项目安装Python、pip和venv创建虚拟环境打开WSL-Remote窗口安装MicrosoftPython扩

【C# 基础精讲】抽象类与接口

抽象类(AbstractClass)和接口(Interface)是面向对象编程中两种重要的概念,它们用于定义类的结构、行为和关系,是实现多态性、代码复用和系统设计的关键手段。在C#及其他面向对象编程语言中,抽象类和接口都发挥着重要作用。本文将详细解释抽象类和接口的概念、特点、用法以及在C#中的应用。1.抽象类的概念与特

同城信息服务源码 本地生活服务小程序源码

同城信息服务源码本地生活服务小程序源码功能介绍:基本设置:网站参数、安全设置、分站管理、支付设置、操作日志、地区设置、公交地铁、国际区号、清理缓存、模板风格、模块管理、域名管理、底部菜单、消息通知、登录设置其他设置:关键词管理、单页文档、网站公告、帮助信息、网站协议、广告设置、友情链接、举报管理、意见反馈、投诉列表短信

CH573-09-BLE蓝牙安卓应用二次开发——RISC-V内核BLE MCU快速开发教程

一、基础工程搭建在上一章最后一讲的BLE蓝牙例程中,我们使用了沁恒官方的BLE调试助手完成数据发送,接下来我们使用AndroidStudio完成一款简易的BLE调试助手。1、参考文章我这里参考了CSDN中的一位博主“摸爬滚打的程序媛”的文章以及对应文章中的AndroidStudioBLE应用工程的Demo。版权声明:链

MP3算法及代码例程

MP3(MPEG-1AudioLayerIII)是一种数字音频压缩算法,用于对音频进行高效的压缩。MP3算法能够显著减小音频文件的大小,同时保持较高的音质。以下是MP3算法的主要步骤:采样率转换:将输入音频信号的采样率转换为固定的值,通常为44.1kHz。这是因为人耳对于音频的感知范围大约在20Hz到20kHz之间,因

9.3.5网络原理(应用层HTTP/HTTPS)

一.HTTP:1.HTTP是超文本传输协议,除了传输字符串,还可以传输图片,字体,视频,音频.2.3.HTTP协议报文格式:a.首行,b.请求头(header),c.空行(相当于一个分隔符,分隔了header和body),d.正文(body).4.5.URL:唯一资源描述符(长度不限制).a.b.注意:查询字符串(qu

第29章_瑞萨MCU零基础入门系列教程之改进型环形缓冲区

本教程基于韦东山百问网出的DShanMCU-RA6M5开发板进行编写,需要的同学可以在这里获取:https://item.taobao.com/item.htm?id=728461040949配套资料获取:https://renesas-docs.100ask.net瑞萨MCU零基础入门系列教程汇总:https://b

【初阶数据结构】树(tree)的基本概念——C语言

目录一、树(tree)1.1树的概念及结构1.2树的相关概念1.3树的表示1.4树在实际中的运用(表示文件系统的目录树结构)二、二叉树的概念及结构2.1二叉树的概念2.2现实中真正的二叉树2.3特殊的二叉树2.4二叉树的性质2.5二叉树的存储结构一、树(tree)1.1树的概念及结构树是一种非线性的数据结构,它是由n(

Softing物联网(IoT)方案之OT/IT数据集成

一利用数据提高效率和绩效多年以来数据集成和工业物联网一直在推动着市场的发展,目前我们已经能够集成并成功使用先进的技术、大量的传感器和复杂的数据格式等。而在工业物联网或工业4.0中,还有运营技术(OT)和信息技术(IT)它们之间的无缝数据交换对于企业提升竞争力而言同样非常重要。将生产和业务数据深度集成到IT层中可为新的利

【Oracle】Oracle系列--Oracle数据类型

文章目录前言1.字符类型2.数字类型3.大对象类型4.时间及时间间隔类型5.其他类型前言ORACLE基本数据类型,又叫内置数据类型(built-indatatypes)可以按类型分为:字符串类型、数字类型、大对象类型(LOB类型)、日期类型、LONGRAW&RAW类型、ROWID&UROWID类型。1.字符类型数据类型

浅说 MySQL 数据库日志有哪些?作用是什么?

目录1.MySQL日志有哪些?2.各种日志分析2.1错误日志2.2二进制日志2.3通用查询日志2.4慢查询日志2.5中继日志2.6数据定义语句日志2.7补充点3.日志有什么用(优点)4.日志的弊端1.MySQL日志有哪些?MySQL数据库为我们提供了很多种不同类型的日志文件,用来存储不同类型的日志。主要有错误日志,二进

热文推荐