React组件通讯

news2025/1/16 17:08:03

组件通讯

组件是一个独立的单元,默认情况下组件只能自己使用自己的数据。在组件化过程中,我们将一个完整的功能拆分成多个组件,便于更好的完成整个应用的功能。

Props

  • 组件本来是封闭的,要接受外部数据应该可以通过Props来实现
  • props的作用:接受传递给组件的数据
  • 传递数据:给组件标签添加属性
  • 接收数据:函数组件通过参数Props接收数据,类组件通过this.props接收数据

函数组件通讯

函数组件

若子组件是函数组件,父组件和子组件之间进行通信的时候,父函数使用属性传递参数,子函数使用函数方法接收props即可。

类组件接收

类组件接收,通过this.props进行访问

import React, {Component} from "react";
import ReactDom from 'react-dom'
import Demo from './Demo'
class App extends Component{
   render(){
       return(
       <div>
           <h1>我是APP组件</h1>
           <Demo car="litter yellow car" money={100}></Demo>
       </div>
   )}
}

ReactDom.render(<App />,document.getElementById('root'))
import {Component} from "react";

export default class Demo extends Component{
    render() {
        const {car,money} = this.props
        return (
            <div>
                <h1>我是Demo组件</h1>
                <p>{car}</p>
                <p>{money}</p>
            </div>
        )
    }
}

props特点

  • 可以给组件传递任意类型的数据
  • props是只读的,不允许修改props的数据,单项数据流
  • 注意:在组件中使用的时候,需要把props传递给super(),否则构造函数无法获取到props
import React, {Component} from "react";
import ReactDom from 'react-dom'
import Demo from './Demo'
class App extends Component{
    state={
        money:100
    }
   render(){
       return(
       <div>
           <h1>我是APP组件</h1>
           <button onClick={this.buy}>购买物品</button>
           <Demo
            name="zs"
            money={this.state.money}
            flag={true}
            fn={()=>{
                console.log('fn函数')
            }}
            list={[1,2,3]}
            user={{name:'zs',age:1}}
           ></Demo>
       </div>
   )}
    buy = () => {
        this.setState(prevState => ({
            money: prevState.money - 10
        }));
    }

}

ReactDom.render(<App />,document.getElementById('root'))
// 函数组件
export default function Demo(props){
    console.log(props)
    return(
        <div>
            <h3>我是DEMO组件</h3>
            <div>金钱{props.money}</div>
        </div>
    )
}

单项数据流,只能由父亲修改子组件参数,子组件只能接收父亲传过来的值,但是子组件不能反向修改父亲的值。

Props特点

  • 可以给组件传递任意类型的数据
  • props是制度的,不允许修改props的数据,单向数据流
  • 注意:在类组件中使用的时候,需要吧props传递给super(),否则构造函数无法访问到props
class Hello extends React.Component{
  constructor(props){
    super(props)
  }
  render(){
    return <div>接收到的数据:{
      this.props.age
    }</div>
  }
}

组件之间的三种通讯

父传子

  1. 副组件提供传递的state数据
  2. 给足子组件标签添加属性,值为state中的数据
  3. 子组件中通过props接受副组件中传递的数据

副组件提供数据并且传递给子组件

import React, {Component} from "react";
import ReactDom from 'react-dom'
import Demo from './Demo'
class App extends Component{
    state={
        lastName:''
    }
   render(){
       return(
       <div>
           <h1>我是APP组件</h1>
            <div>
                配偶:<input type="text" placeholder="请输入配偶的名字" onChange={this.handleChange}/>
            </div>
           <Demo name={this.state.lastName}></Demo>
       </div>
   )
    }
    handleChange = (event) => {
        this.setState({
            lastName: event.target.value,
        });
    };
}

ReactDom.render(<App />,document.getElementById('root'))

子组件

// 函数组件
export default function Demo(props){
    console.log(props)
    return(
        <div>
            <h3>我是DEMO组件</h3>
            <div>金钱{props.name}</div>
        </div>
    )
}

子传父

思路:利用回调函数,父组件提供回掉,子组件调用,将要传递的数据作为回调函数的参数。

  1. 副组件提供一个回调函数(用于接收数据)
  2. 将该函数作为属性的值,传递给子组件
  3. 子组件通过Props调用回调函数
  4. 将子组件函数作为参数传递给回调函数

父组件提供函数并且传递给字符串

import React, {Component} from "react";
import ReactDom from 'react-dom'
import Demo from './Demo'
class App extends Component{
    state={
        lastName:'',
        childen:''
    }
   render(){
       return(
       <div>
           <h1>我是APP组件</h1>
            <div>
                配偶:<input type="text" placeholder="请输入配偶的名字" onChange={this.handleChange}/>
            </div>
           <div>
               子组件传递数据:{this.state.childen}
           </div>
           <Demo name={this.state.lastName} changeName={this.changeName}></Demo>

       </div>
   )
    }
    handleChange = (event) => {
        this.setState({
            lastName: event.target.value,
        });
    };

    changeName = (name)=>{
        console.log('fater accept',name)
        this.setState({childen:name})
    }
}

ReactDom.render(<App />,document.getElementById('root'))

子组件代码

// 函数组件
import {Component} from "react";
export default class Demo extends Component{
    state = {
        wife:'',
    }
    render() {
        return(
            <div>
                <h3>我是DEMO组件</h3>
                <div>金钱{this.props.name}</div>
                <div>
                    配偶的名字:<input type="text" value={this.state.wifi} onChange={this.handleChange}/>
                </div>
            </div>
        )
    }
    handleChange = (e)=>{
        this.setState({wife:e.target.value})
        // 传递给父组件
        this.props.changeName(e.target.value)
    }
}
// export default function Demo(props){
//
//     console.log(props)
//     return(
//         <div>
//             <h3>我是DEMO组件</h3>
//             <div>金钱{props.name}</div>
//             <div>
//                 配偶的名字:<input type="text"/>
//             </div>
//         </div>
//     )
// }

自己做的一个小Demo

思路:父亲给孩子钱,孩子小费多少钱,然后返还给给父亲多少钱

在这个小Demo中父亲会使用input给孩子钱,孩子在接受到父亲给的钱后去超市花钱然后再找零给父亲。

import React, {Component} from "react";
import ReactDom from 'react-dom'
import Demo from './Demo'
class App extends Component{
    state={
        money:'',
        remain:''
    }
   render(){
       return(
       <div>
           <h1>我是APP组件父亲组件</h1>
           给你:<input type="text" onChange={this.handletext}/>
           应该还给我:{this.state.remain}
           <Demo givemoney = {this.state.money} remainmoney={this.remainmoney}></Demo>
       </div>
   )
    }
    handletext = (e)=>{
        this.setState({
            money:e.target.value
        })
    };
    remainmoney = (speedmoneys)=>{
        this.setState({
            remain:this.state.money-speedmoneys
        })
    }
}

ReactDom.render(<App />,document.getElementById('root'))
// 函数组件
import {Component} from "react";
export default class Demo extends Component{
    state = {
        money: '',
        speedmoneys:''
    }
    render() {
        return(
            <div>
                <h3>我是DEMO组件</h3>
                <p>我收到了:{this.props.givemoney}</p>
                我花了:<input type="text" onChange={this.speedmoney}/>
            </div>
        )
    }
    speedmoney = (e)=>{
        this.setState({
            speedmoneys:e.target.value
        })
        this.props.remainmoney(e.target.value)
    }
}

兄弟父子

兄弟组件通讯(没有)

  • 将共享状态提升到最近的公共组件中,由公共父组件管理这个状态
  • 思想:状态提升
  • 公共组件的职责:
    • 提供共享状态
    • 提供共享状态的方法
  • 要通讯的子组件只需通过props接收状态或操作状态的方法

状态提升前

提升状态之后

在这里插入图片描述

context组建通讯

import React from 'react';
import ReactDOM from 'react-dom/client';
import Father from './Father';

//1.创建组件
//2.使用Provider组件包裹根元素,Provider组件就是最大的根元素

const {Provider,Consumer}  = React.createContext()

const root = ReactDOM.createRoot(document.getElementById('root'));
class App extends React.Component {
  state={
    color:'red'
  }
  render() {
    return (
      <Provider value={this.state.color}>
  <div>
  <h1>我是APP组件</h1>
  <Father color = {this.state.color}/>
  </div>
  <Consumer>
  {
    (value)=>{
      return <h1 style={{color:value}}>我是Custom组件</h1>
      }
      }
  </Consumer>
  </Provider>
);
}
}
root.render(<App />);

React使用Consumer进行数据共享,直接使用React.createContext进行创建两个包,使用Provide进行数据展示,然后使用Consumer进行数据共享。
但是数据共享过程中Consumer里面需要用到函数进行引用,使用函数引用的方法才可以进行Consumer设置

使用Childer父传子

import React from 'react';
import ReactDOM from 'react-dom/client';
import Header from './head';
import Dialog from './Dialog';


const root = ReactDOM.createRoot(document.getElementById('root'));
class App extends React.Component {
  render() {
    return (
       <div>
           <h1>children属性</h1>
           <Header>首页</Header>
           <Header>登陆</Header>
           <Dialog title={<h1>温馨提示</h1>}>
               <input type="text"/>
               <button>登陆</button>
               <button>注册</button>
           </Dialog>
       </div>
    );
  }
}
root.render(<App />);

childer可以穿入任意元素,例如button,input等,这里我定义了一个Dialog的组件

import React, {Component} from 'react';

class Dialog extends Component {
    render() {
        return (
            <div>
                <h1>Children属性</h1>
                {this.props.title}  {/* 这里是渲染title */}
                {this.props.children}  {/* 这里是渲染input */}
            </div>
        );
    }
}

export default Dialog;

可以看到我的接收参数只有两个一个是title一个是childern
我的children直接获取父亲节点传过来的所有结构

Props校验

目的:校验接受的props的数据类型,增加组件的健壮性
对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据
如果传入数据格式不对,可能会导致组件内部报错。
组件的使用者不能明确知道报错原因

import React from 'react';
import ReactDOM from 'react-dom/client';
import Header from './head';
import Dialog from './Dialog';


const root = ReactDOM.createRoot(document.getElementById('root'));
class App extends React.Component {
  render() {
    return (
       <div>
           <h1>children属性</h1>
           <Header>首页</Header>
           <Header>登陆</Header>
           <Dialog title={<h1>温馨提示</h1>} list={[1,2,3,4]}>
               <input type="text"/>
               <button>登陆</button>
               <button>注册</button>
           </Dialog>
       </div>
    );
  }
}
root.render(<App />);

import React, {Component} from 'react';
import PropTypes from "prop-types";
class Dialog extends Component {
    render() {
        return (
            <div>
                <h1>Children属性</h1>
                {this.props.title}  {/* 这里是渲染title */}
                {this.props.children}  {/* 这里是渲染input */}
                <ul>
                    {
                        this.props.list.map((item)=>(
                            <li key={item}>{item}</li>
                        ))
                    }
                </ul>
            </div>
        );
    }
}

// 增加校验规则
Dialog.propTypes = {
    title: PropTypes.string,
    list: PropTypes.array
}
export default Dialog;

约束规则:
1.常见类型:array,bool,func,number,object
2.React元素类型:element
3.必填项:isRequired
4.特定的结构对象:shape({})

// 增加校验规则
Dialog.propTypes = {
    title: PropTypes.string.isRequired,
    list: PropTypes.array
}

默认属性

在未传入Props时生效,有默认属性

Dialog.defaultProps={
  pageSize:10
}

在使用组件的时候用户不传入该值,给予默认值设置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1470530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jmeter学习系列之八:控制器Controllers 的入门介绍

一、Controllers 简介 Jmeter有两种类型的控制器&#xff1a;Samplers&#xff08;取样器&#xff09;和Logical Controllers&#xff08;逻辑控制器&#xff09;&#xff1b;它们驱动着测试的进行取样器&#xff1a;让jmeter发送请求到服务器以及接收服务器的响应数据逻辑控制…

三种方法用c语言求最大公约数以及最小公倍数

学习目标&#xff1a; 掌握求最大公约数&#xff08;最小公倍数&#xff09;的三种基本方法 学习内容&#xff1a; 1.一大一小取其小&#xff0c;剖根问底取公约 意思是从一大一小两个数当中&#xff0c;我们取较小的那个数&#xff08;min&#xff09;进行剖析&#xff0c;试…

Socket、UDP、TCP协议和简单实现基于UDP的客户端服务端

目录 Socket TCP和UDP区别 UDP&#xff1a;无连接&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工 TCP&#xff1a;有连接&#xff0c;可靠传输&#xff0c;面向字节流&#xff0c;全双工 无连接和有连接 可靠传输和不可靠传输 面向数据报和面向字节流…

pclpy 最小二乘法拟合平面

pclpy 最小二乘法拟合平面 一、算法原理二、代码三、结果1.左边原点云、右边最小二乘法拟合平面后点云投影 四、相关数据 一、算法原理 平面方程的一般表达式为&#xff1a; A x B y C z D 0 ( C ≠ 0 ) Ax By Cz D 0 \quad (C\neq0) AxByCzD0(C0) 即&#xff1a; …

【深度学习笔记】 3_13 丢弃法

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.13 丢弃法 除了前一节介绍的权重衰减以外&#xff0c;深度学习模型常常使用丢弃法&#xff08;dropout&#xff09;[1] 来应对过拟合…

HDL FPGA 学习 - Quartus II 工程搭建,ModelSim 仿真,时序分析,IP 核使用,Nios II 软核使用,更多技巧和规范总结

目录 工程搭建、仿真与时钟约束 一点技巧 ModelSim 仿真 Timing Analyzer 时钟信号约束 SignalTap II 使用 In-System Memory Content Editor 使用 记录 QII 的 IP 核使用 记录 Qsys/Nios II 相关 记录 Qsys 的 IP 核使用 封装 Avalon IP 更多小技巧教程文章 更多好…

【C语言】linux内核ipoib模块 - ipoib_tx_poll

一、中文注释 这段代码是 Linux 内核网络栈中与 InfiniBand 协议相关的一个部分&#xff0c;特别是与 IP over InfiniBand (IPoIB)相关。该函数负责去处理IPoIB的发送完成队列&#xff08;发送CQ&#xff09;上的工作请求&#xff08;work completions&#xff09;。以下是对这…

前后端分离Vue+ElementUI+nodejs蛋糕甜品商城购物网站95m4l

本文主要介绍了一种基于windows平台实现的蛋糕购物商城网站。该系统为用户找到蛋糕购物商城网站提供了更安全、更高效、更便捷的途径。本系统有二个角色&#xff1a;管理员和用户&#xff0c;要求具备以下功能&#xff1a; &#xff08;1&#xff09;用户可以修改个人信息&…

YOLO系列论文阅读(v1--v3)

搞目标检测&#xff0c;绕不开的一个框架就是yolo&#xff0c;而且更糟糕的是&#xff0c;随着yolo的发展迭代&#xff0c;yolo网络可以做的事越来越多&#xff0c;语义分割&#xff0c;关键点检测&#xff0c;3D目标检测。。。这几天决定把YOLO系列彻底梳理一下&#xff0c;在…

奇异递归模板模式应用6-类模板enable_shared_from_this

异步编程中存在一种场景&#xff0c;需要在类中将该类的对象注册到某个回调类或函数中&#xff0c;不能简单地将this传递给回调类中&#xff0c;很可能因为回调时该对象不存在而导致野指针访问&#xff08;也有可能在析构函数解注册时被回调&#xff0c;造成对象不完整&#xf…

【变压器故障诊断分类及预测】基于GRNN神经网络

课题名称&#xff1a;基于GRNN神经网络的变压器故障诊断分类及预测 版本日期&#xff1a;2024-02-10 运行方式&#xff1a;直接运行GRNN0507.m文件 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 对变压器油中溶解气体进行分析是变压器…

基于springboot+vue的精准扶贫管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

前端工程化面试题 | 15.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Linux系统前后端分离项目

目录 一.jdk安装 二.tomcat安装 三.MySQL安装 四.nginx安装 五.Nginx负载均衡tomcat 六.前端部署 一.jdk安装 1. 上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录&#xff0c;将安装包拖进去 2. 解压安装包 这里需要解压到usr/local目录下&#xff0c;在这里新建一个…

基于yolov5的电瓶车和自行车检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的电瓶车和自行车检测系统_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的电瓶车和自行车检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#xff0c;包括代码&#xff0c;数据集&#xff0c;训练好的模型…

低于API等级30的应用将无法在上述应用商店

minSdkVersion minSdkVersion用于指定应用兼容的最低Android版本&#xff08;API等级&#xff09;。 如果APP某些功能无法支持低版本Android系统的设备&#xff0c;可以配置minSdkVersion确保APP只能安装到指定Android版本以上的设备。HBuilder|HBuilderX中可在manifest.json中…

单词倒排——c语言解法

以下是题目&#xff1a; 这个题中有三个点&#xff0c; 一个是将非字母的字符转换为空格&#xff0c; 第二是如果有两个连续的空格&#xff0c; 那么就可以将这两个连续的空格变成一个空格。 第三个点就是让单词倒排。 那么我们就可以将这三个点分别封装成三个函数。 还有就是…

Spring Security源码学习

Spring Security本质是一个过滤器链 过滤器链本质是责任链设计模型 1. HttpSecurity 【第五篇】深入理解HttpSecurity的设计-腾讯云开发者社区-腾讯云 在以前spring security也是采用xml配置的方式&#xff0c;在<http>标签中配置http请求相关的配置&#xff0c;如用户…

Linux下的版本控制系统——Git:初学者指南

引言 在软件开发的世界中&#xff0c;版本控制是一项至关重要的技术。它允许开发者追踪和管理代码的变更历史&#xff0c;协同工作&#xff0c;并在必要时恢复到之前的版本。而在Linux系统下&#xff0c;Git已经成为事实上的版本控制标准。本文将带领大家走进Git的世界&#x…

【人脸朝向识别与分类预测】基于PNN神经网络

课题名称&#xff1a;基于PNN神经网络的人脸朝向识别分类 版本日期&#xff1a;2024-02-20 运行方式&#xff1a;直接运行PNN0503.m文件 代码获取方式&#xff1a;私信博主或 QQ:491052175 模型描述&#xff1a; 采集到一组人脸朝向不同角度时的图像&#xff0c;图像来自不…