React中组件通信01——props

news/2024/7/15 19:20:15 标签: react.js, 前端, 前端框架

React中组件通信01——props

  • 1. 父传子——props
    • 1.1 简单例子——props
    • 1.2 props 可以传递任何数据
      • 1.2.1 传递数字、对象等
      • 1.2.2 传递函数
      • 1.2.3 传递模版jsx
  • 2. 子传父 + 子传子——props
    • 2.1 父传子——传递函数
    • 2.2 子传父——通过父传子的函数实现
    • 2.3 优化 + 子传子(兄弟通信)
  • 3. render props
    • 3.1 组件标签上的标签体内容 传递
    • 3.2 render props
  • 4. 附代码:

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;
    

http://www.niftyadmin.cn/n/5032366.html

相关文章

typescript字面量类型

typescript 字面量介绍 在TypeScript中&#xff0c;字面量是指在代码中直接使用的具体值&#xff0c;如字符串、数字、布尔值等。字面量类型是TypeScript中的一种特殊类型&#xff0c;它用于定义一组有限的值&#xff0c;并且可以在定义变量或函数时使用字面量作为具体值&…

基于图像处理的车牌定位算法改进研究

目 录 1引言 1.1 研究的目的和意义 1 1.2 发展现状及应用 2 1.3 本文内容及主要工作 2 2相关知 识 2.1 位图的基础知识 3 2.2 位图的基本操作 3 2.3 车牌的基本特征 4 2.4 车牌定位的工作原理 5 2.5 要达到的设计目标 5 3经典算法的分析 3.1 灰度转换算…

【单线图的系统级微电网仿真】基于 PQ 的可再生能源和柴油发电机组微电网仿真(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

常见的API

常见的 API Math 从 JDK 版本 1 开始的, 用来计算的一些方法 这里面定义了两个常量的 PI 和 E 这两个是最接近 pi 的值和最接近对数的值 Abs (int a ) 取绝对值Ceil (double a)向上取整Floor (double a )向下取整Round (float a)四舍五入Max (int a, int b) 取最大值Pow (dou…

linux查看进程对应的线程(数)

首先&#xff0c;top或ps查看进程列表&#xff0c;确定要查看的进程pid&#xff0c;如下面40698 查看进程的线程情况 查看进程&#xff1a;top -p 40698 查看线程&#xff1a;top -p 40698 -d 3 -H 其中-d是刷新频率 可看到此进程共211个线程&#xff0c;运行中的是211个。…

【Linux学习笔记】权限

1. 普通用户和root用户权限之间的切换2. 权限的三个w2.1. 什么是权限&#xff08;what&#xff09;2.1.1. 用户角色2.1.2. 文件属性 2.2. 怎么操作权限呢&#xff1f;&#xff08;how&#xff09;2.2.1. ugo-rwx方案2.2.2. 八进制方案2.2.3. 文件权限的初始模样2.2.4. 进入一个…

vue中封装websocket,全局调用

项目场景&#xff1a; 项目中多个地方,多个页面的数据需要同一个websocket实时推送. 解决方案&#xff1a; 第一步,全局创建一个global.js,定义全局变量 export default {ws: {},setWs: function(newWs) {this.ws newWs} }第二步,在main.js中引入global.js,并将global的文件挂…

解决Springboot使用Junit测试时对数据库的修改无效

现象 在使用Junit做单元测试的过程中&#xff0c;比如对mybatis的dao进行单元测试&#xff0c;发现对数据库的select操作正常&#xff0c;可以获取数据&#xff0c;但insert、update、delete操作即使运行不报错&#xff0c;仍然不能不能对数据产生修改和插入。 原因和解决 原…