• React中组件通信01——props


    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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      {props.render()}
      
      • 1
    • 传参数的情况,这里的函数名习惯用render,所以叫 render props ,如下:
      在这里插入图片描述
       <div className="childE">
           <ChildE dogList={this.state.dogList} 
                   testJsx={<p>测试一下传递jsx</p>}
                   // render={()=>}
                   render={(kind)=><F petKind={kind}/>}
                   />
       </div>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      {props.render('狗狗')}
      
      • 1
      接到E传来的宠物类型是:{props.petKind}
      
      • 1

    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={()=>}
                                  render={(kind)=><F petKind={kind}/>}
                                  />
                      </div>
                  </div>
              )
          }
      }
      
      export default Parent;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
    • xxxA.jsx
      import React from "react";
      
      class ChildA extends React.Component{
          render(){
              return(
                  <div>
                      我是子组件A!!!——类式组件
                      <br /><br />
                      收到来自于父组件的数据:{this.props.notice}
                  </div>
              )
          }
      }
      
      export default ChildA;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 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;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 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;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
    • 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;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • 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;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
    • F.jsx
      function F(props){
      
          return(
              <div>
                  我是E组件的子组件,我是F!!!——函数组件
                  <br />
                  接到E传来的宠物类型是:{props.petKind}
              </div>
          )
      }
      
      export default F;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
  • 相关阅读:
    竞赛选题 疫情数据分析与3D可视化 - python 大数据
    Servlet运行原理_API详解_请求响应构造进阶之路(Servlet_2)
    Reactor 之 Spring Boot + Reactor 整合熔断限流 Resilience4j
    如何安全驾驭物联网视频革命
    【LeetCode】回文对 [H](Manacher算法)
    前端js获取key值方法
    漏洞复现:通过CVE-2022-30190上线CS
    基于stm32单片机的输入捕获测量脉宽Proteus仿真
    一、Azkaban简明笔记
    基于Leaflet的leaflet-sidebar侧边栏组件集成
  • 原文地址:https://blog.csdn.net/suixinfeixiangfei/article/details/132940751