首页 > 其他分享 >React 组件通信总结

React 组件通信总结

时间:2022-11-23 21:24:51浏览次数:42  
标签:总结 return render Component React state extends 组件 class

React 组件通信总结

父子通信

  • 传递数据(父传子)与传递方法(子传父)

    /*
     * @Author: HuangBingQuan [email protected]
     * @Date: 2022-11-21 16:02:17
     * @LastEditors: HuangBingQuan [email protected]
     * @LastEditTime: 2022-11-21 16:48:31
     * @FilePath: /react_test/src/02-advanced/01-子传父.js
     * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
     */
    import React, { Component } from 'react'
    
    class Navbar extends Component {
      render() {
        return (
          <div style={{background: "red"}}>
            {/* <button onClick={()=> {
              let that = this.props.that;
              console.log(that.state.SidebarIsShow);
              that.setState({
                SidebarIsShow: !that.state.SidebarIsShow
              })
            }}>click</button> */}
            <button 
              onClick={()=> {
                // 子通知父,让父的SidebarIsShow 取反
                this.props.event() // 调用父组件传来的回调函数
              }}
            >
              click
            </button>
            <span>NavBar</span>
          </div>
        )
      }
    }
    
    class Sidebar extends Component {
      render() {
        return (
          <div style={{background: "yellow", width: "200px"}}>
            <ul>
              <li>111111</li>
              <li>111111</li>
              <li>111111</li>
              <li>111111</li>
              <li>111111</li>
              <li>111111</li>
            </ul>
          </div>
        )
      }
    }
    
    export default class App extends Component {
      state = {
        SidebarIsShow: false
      }
      render() {
        return (
          <div>
            {/* <Navbar that={this}></Navbar> */}
            {/*  */}
            <Navbar event={()=> {
              this.setState({
                SidebarIsShow: !this.state.SidebarIsShow
              })
            }}></Navbar>
    
            {/* <Sidebar></Sidebar> */}
            { this.state.SidebarIsShow && <Sidebar></Sidebar> }
          </div>
        )
      }
    }
    
    
  • ref标记(父组件拿到子组件的引用,从而调用子组件的方法)

    /*
     * @Author: HuangBingQuan [email protected]
     * @Date: 2022-11-21 21:38:26
     * @LastEditors: HuangBingQuan [email protected]
     * @LastEditTime: 2022-11-22 16:51:06
     * @FilePath: /react_test/src/02-advanced/04-父子通信版-表单域组件.js
     * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
     */
    import React, { Component } from 'react'
    
    class Filed extends Component {
      state = {
        val: ""
      }
      render() {
        return (
          <div style={{background: "yellow"}}>
            <label>{this.props.label}</label>
            <input type={this.props.type} value={this.state.val} onChange={(evt)=> {
              this.setState({
                val: evt.target.value
              })
            }}></input>
          </div>
        )
      }
      clear() {
        this.setState({
          val: ""
        })
      }
      setValue(value) {
        this.setState({
          val: value
        })
      }
    }
    
    export default class App extends Component {
      userName = React.createRef();
      password = React.createRef()
      render() {
        return (
          <div>
            <h1>登录页面</h1> 
            <Filed ref={this.userName} label="用户名" type="text" ></Filed>
            <Filed ref={this.password} label="密码" type="password"></Filed>
            <button onClick={()=> {
              console.log(this.userName.current);
              console.log(this.password.current);
              console.log(`账号:${this.userName.current.state.val}-密码:${this.password.current.state.val}`);
            }}>登录</button>
            <button onClick={()=> {
              this.userName.current.clear()
              this.password.current.clear()
            }}>取消</button>
            <div style={{background: "#ff2121"}}>
              <svg style={{width: "20px"}} t="1669106904741" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3653" width="200" height="200"><path d="M513.506307 974.330764c-62.755276 0-123.643018-12.295024-180.971701-36.543288-55.363935-23.416316-105.081267-56.935734-147.772578-99.626022-42.690288-42.690288-76.209706-92.408643-99.626022-147.771555-24.248264-57.328683-36.542264-118.216425-36.542264-180.971701s12.295024-123.643018 36.542264-180.972724c23.416316-55.364959 56.935734-105.08229 99.626022-147.773601s92.408643-76.210729 147.772578-99.628068c57.328683-24.248264 118.216425-36.543288 180.971701-36.543288 62.755276 0 123.643018 12.295024 180.972724 36.543288 55.364959 23.417339 105.08229 56.936757 147.773601 99.628068s76.211752 92.409666 99.628068 147.773601c24.248264 57.329706 36.543288 118.217449 36.543288 180.972724s-12.295024 123.643018-36.543288 180.971701c-23.417339 55.363935-56.93778 105.081267-99.628068 147.771555-42.691311 42.691311-92.409666 76.210729-147.773601 99.627045C637.150348 962.03574 576.262606 974.330764 513.506307 974.330764zM513.506307 82.074274c-57.69912 0-113.661689 11.296277-166.334329 33.5757-50.884924 21.522176-96.587825 52.338019-135.840828 91.591021-39.251979 39.251979-70.066799 84.955904-91.588975 135.841851-22.278399 52.67264-33.574676 108.636233-33.574676 166.335353s11.296277 113.662713 33.574676 166.334329c21.522176 50.885947 52.338019 96.588849 91.588975 135.839805 39.251979 39.251979 84.955904 70.067822 135.840828 91.589998 52.67264 22.278399 108.635209 33.574676 166.334329 33.574676s113.662713-11.295254 166.335353-33.574676c50.885947-21.522176 96.589872-52.338019 135.841851-91.589998 39.253002-39.250956 70.068845-84.955904 91.591021-135.839805 22.278399-52.67264 33.5757-108.635209 33.5757-166.334329 0-57.69912-11.296277-113.662713-33.5757-166.335353-21.522176-50.885947-52.338019-96.589872-91.591021-135.841851s-84.955904-70.068845-135.841851-91.591021C627.170043 93.370551 571.205427 82.074274 513.506307 82.074274z" p-id="3654"></path><path d="M507.742023 722.763215c-10.376325 0-18.786878-8.411577-18.786878-18.786878L488.955144 590.364789c0-73.891917 51.429323-99.112322 96.804766-121.363092 52.704362-25.845645 98.219999-48.165999 88.23867-139.822512-3.546779-32.550347-19.739577-57.901735-48.130184-75.352175-28.942169-17.788132-69.626777-26.617218-117.695562-25.511024-34.110889 0.781806-66.710354 10.963703-94.273107 29.447682-27.16264 18.215874-48.102554 43.559075-60.554144 73.290213-4.009314 9.56996-15.017018 14.07967-24.585955 10.07138-9.570983-4.00829-14.07967-15.015995-10.07138-24.585955 15.304568-36.540218 40.990576-67.654866 74.283844-89.981361 33.519418-22.478967 73.057923-34.859949 114.341165-35.806507 55.296397-1.2689 103.106286 9.476839 138.229225 31.064506 38.252209 23.51046 61.008492 59.228963 65.808822 103.294574 12.836353 117.857245-54.744835 150.998039-109.046578 177.627537-21.070898 10.332323-40.972157 20.091594-54.872748 33.641191-14.455223 14.089903-20.901029 30.739095-20.901029 53.986565L526.530948 703.976336C526.528901 714.351638 518.117324 722.763215 507.742023 722.763215z" p-id="3655"></path><path d="M531.058055 810.18631c0 10.721179-8.691963 19.413142-19.417235 19.413142-10.721179 0-19.413142-8.691963-19.413142-19.413142 0-10.725272 8.691963-19.417235 19.413142-19.417235C522.366092 790.768051 531.058055 799.461037 531.058055 810.18631z" p-id="3656"></path></svg>
            </div>
          </div>
        )
      }
    }
    
    

非父子组件通信

  • 状态提升(中间人模式)

    • React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件
    /*
     * @Author: HuangBingQuan [email protected]
     * @Date: 2022-11-23 15:08:14
     * @LastEditors: HuangBingQuan [email protected]
     * @LastEditTime: 2022-11-23 16:34:32
     * @FilePath: /react_test/src/02-advanced/06-中间人模式.js
     * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
     */
    import React, { Component } from 'react'
    import axios from 'axios';
    import './css/communinaion.scss'
    class FilmItem extends Component {
      render() {
        // console.log(this.props);
        let { name, poster, grade, synopsis, callback } = this.props;
        return (
          <div className='filmitem' onClick={(e)=> {
            callback(synopsis)
          }}>
            <img src={poster} alt={name}></img>
            <h4>{name}</h4>
            <div>观众评分:{grade}</div>
          </div>
        )
      }
    }
    
    class FilmDetail extends Component {
      render() {
        return (
          <div className='filmdetail'>{this.props.con}</div>
        )
      }
    }
    
    export default class App extends Component {
      constructor() {
        super();
        this.state = {
          filmList: [],
          con: ""
        }
        this.getData()();
      }
      getData() {
        return async()=> {
          let { data: { data: { films } } } = await axios({ url: "/test.json", method: "get" });
          console.log( films );
          this.setState({
            filmList: films
          })
        }
      }
      render() {
        return (
          <div>
            { 
              this.state.filmList.map(item =>
                <FilmItem key={item.filmId} {...item} callback={(value)=> {
                  this.setState({
                    con: value
                  })
                }}></FilmItem>
              )
            }
            <FilmDetail con={this.state.con}></FilmDetail>
          </div>
        )
      }
    }
    
    
  • 发布订阅模式实现

    /*
     * @Author: HuangBingQuan [email protected]
     * @Date: 2022-11-23 15:08:14
     * @LastEditors: HuangBingQuan [email protected]
     * @LastEditTime: 2022-11-23 18:54:31
     * @FilePath: /react_test/src/02-advanced/06-中间人模式.js
     * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
     */
    import React, { Component } from 'react'
    import axios from 'axios';
    import './css/communinaion.scss'
    
    // 调度中心
    var bus = {
      list: [],
      // 订阅
      subscribe(callback) {
        // console.log(callback);
        this.list.push(callback)
      },
      // 发布
      publish(text) {
        // 遍历注册集合,执行回调函数
        this.list.forEach(callback => {
          callback && callback(text)
        })
      }
    }
    
    class FilmItem extends Component {
      render() {
        // console.log(this.props);
        let { name, poster, grade, synopsis } = this.props;
        return (
          <div className='filmitem' onClick={(e)=> {
            bus.publish(synopsis)
          }}>
            <img src={poster} alt={name}></img>
            <h4>{name}</h4>
            <div>观众评分:{grade}</div>
          </div>
        )
      }
    }
    
    class FilmDetail extends Component {
      constructor() {
        super();
        this.state = {
          con: ""
        }
        bus.subscribe((con)=> {
          this.setState({
            con,
          })
        })
      }
      render() {
        return (
          <div className='filmdetail'>{this.state.con}</div>
        )
      }
    }
    
    export default class App extends Component {
      constructor() {
        super();
        this.state = {
          filmList: [],
        }
        this.getData()();
      }
      getData() {
        return async()=> {
          let { data: { data: { films } } } = await axios({ url: "/test.json", method: "get" });
          console.log( films );
          this.setState({
            filmList: films
          })
        }
      }
      render() {
        return (
          <div>
            { 
              this.state.filmList.map(item =>
                <FilmItem key={item.filmId} {...item} callback={(value)=> {
                  this.setState({
                    con: value
                  })
                }}></FilmItem>
              )
            }
            <FilmDetail></FilmDetail>
          </div>
        )
      }
    }
    
    
  • context状态数传参

    import React, { Component } from 'react'
    const GlobalContext = React.createContext()
    class App extends Component {
      constructor() {
        super();
        this.state = {
          info: ""
        }
      }
      render() {
        return (
        	// 供应数据
          <GlobalContext.Provider value={{
          	info: this.state.info,
          	changeInfo: (val)=> {
          		this.setState({
                info: val
              })
       			}
          }}>
          	<Test></Test>
          </GlobalContext.Provider>
        )
      }
    }
    
    class Test extends Component {
      render() {
        return (
        	// 消费数据
          <GlobalContext.Consumer>
          	{ 
              (value)=> {
          			return (
                	<div>{value.info}</div>
                )
        			}
      			}
          </GlobalContext.Consumer>
        )
      }
    } 
    

标签:总结,return,render,Component,React,state,extends,组件,class
From: https://www.cnblogs.com/bingquan1/p/16920001.html

相关文章

  • JAR包部署相关总结
    指定jdk版本部署C:\Users\Desktop>jar包的位置(demo.jar)D:\develop\jdk\bin\指定版本jdk中bin的位置(一定包含\)运行示例C:\Users\Deskt......
  • ElementUi Upload组件判断文件是否上传中
    //是否存在上传中letisUploading=falsefunctionbroadcast(componentName,eventName,params){ this.$children.forEach(child=>{  varname=child.......
  • JVM秋招总结
    JVM是Java相关知识中重要的一大块,这里记录一下自己的学习思路,以及印象比较深刻的知识点和面试问题个人总结思路思路顺着一次Java程序运行中,涉及到的JVM部分总结首先为......
  • 第九周助教总结
    作业要求作业提交地址第九周作业作业具体内容作业提交情况其中朱田育同学两个账号均为提交,即七位同学未及时提交作业。作业问题:优点:1.部分同学能够很好地总结上......
  • 计算机网络面试大总结
    本文分文五大部分,第一部分总纲说明计算机网络层次划分的三种模型,一到四部分以TCP/IP协议模型作为划分标准,分别说明各层作用和最常见的面试题,最后总结网络综合面试题,历时六天......
  • 篇(20)-Asp.Net Core入门实战-完结之一期阶段总结
    入门实战-完结之一期阶段总结用了几天的功夫,编写和演练的这个Asp.NetCore简单入门的教程已经讲完,下一期可以将完善其功能,将UI功能也给其套上,至少可以达到商用的目的。简......
  • 数据统计与可视化复习总结(二):非参数检验、生存分析
    前面所介绍的各种检验法,是在总体分布类型已知的情况下,对其中的未知参数进行检验统称为参数检验.在实际问题中,有时我们并不能确切预知总体服从何种分布,这时就需要根据来自......
  • 2021牛客OI赛前集训营-提高组(第四场)总结
    概述预估得分:\(100+100+30+50=280\)实际得分:\(30+50+30+45=165\)T1最终测试题目大意\(n\)名选手,第\(i\)名选手的得分有\(0,\;a_{i,0},\;a_{i,......
  • Vue遍历data中某个字段并累加,res.result.forEach方法总结
    forEach的定义和方法:forEach()方法用于调用数组的每个元素,并将元素传递给回调函数。注意:forEach()对于空数组是不会执行回调函数的。一、html部分<divclass="tab-con......
  • vue组件-文本超出显示点点点且悬浮可查看所有内容
    需求当文本超出的时候需要显示点点点,然后鼠标悬浮其上要能查看所有的文本内容。就直接封装一个通用的组件。依赖项element-plusvue3组件存放目录新建vue文件/compo......