React组件通讯

组件通讯

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

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
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencv图像处理

// 提取路口轮廓集合&#xff08;每个路口的轮廓为一系列点集&#xff09; std::vector<std::vector<cv::Point>> node_contours; std::vector<cv::Vec4i> node_hierarchy;保存轮廓的层次关系// 只提取外轮廓 轮廓近似方法&#xff1a;水平垂直对角线只保留端…

CSP-202209-3-防疫大数据

CSP-202209-3-防疫大数据 解题思路 一、数据结构定义 对于大模拟的题&#xff0c;合适的数据结构选择十分重要&#xff0c;正确的数据结构选择能够有效的提升解题效率 // 漫游消息结构体 struct RoamingData {int date, user, region; };vector<RoamingData> roamin…

C#与VisionPro联合开发——TCP/IP通信

TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;是一组用于在网络上进行通信的通信协议。它是互联网和许多局域网的基础&#xff0c;为计算机之间的数据传输提供了可靠性、有序性和错误检测。在软件开发中&#xff0c;TCP/IP 通信通常用于实现网络应用程序之间的数据交…

YOLOv5算法进阶改进(17)— 添加BiFormer注意力机制 | 提升小目标检测精度

前言:Hello大家好,我是小哥谈。本文主要通过对YOLOv5模型添加Bifommer注意力机制为例,让大家对于YOLOv5模型添加注意力机制有一个深入的理解,通过本文你不仅能够学会添加Biformer注意力机制,同时可以举一反三学会其他的注意力机制的添加。🌈 前期回顾: YOLOv5算法进…

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(八)NodeJS入门——http模块

一念心清净&#xff0c;处处莲花开。 055_http模块_网页资源加载基本过程 哈喽&#xff0c;大家好&#xff0c;这一课节我们来介绍一下网页资源加载的基本过程。首先先强调一点&#xff0c;这个内容对于我们后续学习非常非常的关键&#xff0c;所以大家务必要将其掌握。 首先先…

hbuilderx创建、运行uni-app

创建uni-app 在点击工具栏里的文件 -> 新建 -> 项目&#xff1a; 选择uni-app类型&#xff0c;输入工程名&#xff0c;选择模板&#xff0c;点击创建&#xff0c;即可成功创建。 uni-app自带的模板有 Hello uni-app &#xff0c;是官方的组件和API示例。还有一个重要模…

人人都是项目管理者,项目管理的基础入门

一、教程描述 本套教程旨在系统介绍项目管理的方法论&#xff0c;帮助大家认识、熟悉、体验、思考项目管理&#xff0c;全面掌握项目管理的流程与方法&#xff0c;快速成长为时代紧缺型的项目管理人才。本套项目管理入门教程&#xff0c;大小805.40M&#xff0c;共有13个文件。…

智慧农业—农业资源数据中心

综述 农业资源数据中心建设的目标是将大量的农业生产信息通过采集、清洗、核准后实现统一存储、统一管理,实现数据的共享和集中管理,保障数据的安全,也为数据的挖掘分析提供决策分析创造条件。 农业资源数据中心的数据架构如下图所示: (1)农业专家数据库。主要收录国内、…

三步实现SpringBoot全局日志记录,整合Echarts实现数据大屏

&#x1f680; 注重版权&#xff0c;转载请注明原作者和原文链接 小袁博客&#xff1a;https://boke.open-yuan.com/小袁博客后台&#xff1a;https://boke.open-yuan.com/back-manager/更多项目内容关注小红书&#x1f50d;OpenYuan开袁 http://xhslink.com/I9zNaC有需求可以在…

vue 手势解锁功能

效果 实现 <script setup lang"ts"> const canvasRef ref<HTMLCanvasElement>() const ctx ref<CanvasRenderingContext2D | null>(null) const width px2px(600) const height px2px(700) const radius ref(px2px(50))const init () > …

【AI链接】 大模型语言模型网站链接

目录 GPT类1. chatgpt2. GROP3. Google AI Studio4. Moonshot AI (国内) 解读论文类&#xff1a;1. txyz 编程辅助插件&#xff1a;1. Fitten Code GPT类 1. chatgpt https://chat.openai.com/ 2. GROP https://groq.com/ 3. Google AI Studio https://aistudio.google…

计算机网络:思科实验【3-集线器与交换机的区别、交换机的自学习算法】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;Cisco Packet Tracer实验 本文对应的实验报告源文件请关注微信公众号程序员刘同学&#xff0c;回复思科获取下载链接。 实验目的实验环境实验内容集线器与交换机的区别交换机的自学习算法…

南京观海微电子----Verilog基础(一)——数据类型、运算符

1. 数据类型 1.1 常量 整数&#xff1a;整数可以用二进制b或B&#xff0c;八进制o或O&#xff0c;十进制d或D&#xff0c;十六进制h或H表示&#xff0c;例如&#xff0c;8’b00001111表示8位位宽的二进制整数&#xff0c;4’ha表示4位位宽的十六进制整数。 X和Z&#xff1a;X…

Github 2024-02-21 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-21统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目8非开发语言项目1TypeScript项目1 gpt4free 语言模型集合改进计划 创建周期&#xff1a;300 天开…

Excel的中高级用法

单元格格式&#xff0c;根据数值的正负分配不同的颜色和↑ ↓ 根据数值正负分配颜色 2-7 [蓝色]#,##0;[红色]-#,##0 分配颜色的基础上&#xff0c;根据正负加↑和↓ 2↑-7↓ 其实就是在上面颜色的代码基础上加个 向上的符号↑&#xff0c;或向下的符号↓ [蓝色]#,##0↑;[红色…

vivo 基于 StarRocks 构建实时大数据分析平台,为业务搭建数据桥梁

在大数据时代&#xff0c;数据分析和处理能力对于企业的决策和发展至关重要。 vivo 作为一家全球移动互联网智能终端公司&#xff0c;需要基于移动终端的制造、物流、销售等各个方面的数据进行分析以满足业务决策。 而随着公司数字化服务的演进&#xff0c;业务诉求和技术架构有…

动态规划课堂1-----斐波那契数列模型

目录 动态规划的概念&#xff1a; 动态规划的解法流程&#xff1a; 题目: 第 N 个泰波那契数 解法&#xff08;动态规划&#xff09; 代码&#xff1a; 优化&#xff1a; 题目&#xff1a;最小花费爬楼梯 解法&#xff08;动态规划&#xff09; 解法1&#xff1a; 解…

【QT 5 +Linux下软件生成+qt软件生成使用工具+学习他人文章+第一篇:使用linuxdeployqt软件生成】

【QT 5 Linux下软件生成qt软件生成使用工具学习他人文章第一篇&#xff1a;使用linuxdeployqt软件生成】 1、前言2、实验环境3、自我学习总结-本篇总结1、新手的疑问&#xff0c;做这件事的目的2、了解工具&#xff1a;linuxdeployqt工具3、解决相关使用过程中问题 4、参照文章…

5分钟轻松帮你EasyRecovery恢复女朋友照片

相信有不少男性电脑玩家都会将女朋友的照片存放在电脑硬盘之内&#xff0c;作为珍贵的收藏和回忆。但是在某些时候&#xff0c;如果我们错误地删除了这些照片&#xff0c;或者由于系统问题导致其中的照片丢失&#xff0c;那么我们怎么找回女朋友的照片&#xff1f;这个问题就足…

进程的学习

进程基本概念: 1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态查看当前系统中的所有进程信息&#xff08;根据CPU占用率排序&#xf…