react3:受控组件(表单默认变成受控)-组件通信 - typescript项目(表单,tabbar)

news2025/1/16 13:52:43

受控组件:表单

  1. 非受控组件表单元素值不受所在组件状态的控制, 我们将这样的表单元素称作: 非受控组件.
  2. 受控组件受控组件 : 值受到 React 组件状态控制的表单元素一般是通过 defaultValue 属性, onChange 事件配合将非受控组件变为受控组件.
  3. 多表单元素操作 :4,5,6
  4. 给表单元素添加 name 属性,名称与 state 相同
  5. 根据表单元素类型获取对应值
  6. change 事件处理程序中通过 [name] 来修改对应的 state

通过value和onChange事件,让表单元素变成 受控组件

复选框,是否勾选 checked={ }, 配合onChange事件

获取最新input值

操作value使其变成受控组件(文本框、富文本框、下拉框)

name判断点的哪个

[ ]:可以对其中的表达式进行取值预算:取值结束,[ ] 就没有了

e.target        获取目标对象

e.target.type        获取元素类型

e.target.name        获取元素的name

e.target.type="checkbox"         获取元素的复选状态

e.target.value        获取元素的值

value获取表单元素的值

 升级:name 判断,考虑表单提交的很多元素比较麻烦

 升级:[ ] 对其中表达式取值预算,取值结束 [ ] 就没了

复选框

 

代码如下:::

import React, { Component } from 'react';
import './App.scss'
// react应用的组件有两种创建方式:函数式组件,类组件
// rcc 创建calss组件
// rsf创建函数式组件

class App extends Component {
  constructor(props){
    super(props)
    // 定义组件状态
    this.state={
      loginname:'',
      password:'',
      isread:false
    }
  }
  handleChange(e){
    console.log(e.target);
    // if (e.target.name == 'loginname') {
    //   this.setState({loginname:e.target.value})
    // }else if(e.target.name == 'password'){
    //   this.setState({password:e.target.value})
    // }

    //[] 可以对其中的表达式进行取值运算,取值结束,[] 就没有了

    // e.target  //获取目标对象
    // e.target.type  //获取元素类型
    // e.target.name //获取元素的name
    // e.target.type='checkbox' //元素的复选状态
    // e.target.value //元素的值

    // name名和state中名一样,那就可以这样简写了,一次修改所有表单元素的值 
    this.setState({[e.target.name]:e.target.type == "checkbox" ? e.target.checked : e.target.value})
  }
  login(){
    console.log(this.state);
  }
  render() {
    return (
      <div className='login'>
        <div className='block'>
            {/* 通过 value属性 和 onChange事件 让表单元素变成 受控元素 */}
            <input name='loginname' type="text" placeholder='输入账号' value={this.state.loginname} onChange={(e)=>{this.handleChange(e)}} />
        </div>
        <div className='block'>
            {/* 通过value属性 和 onChange事件 让表单元素变成 受控元素 */}
            <input name='password' type="password" placeholder='输入密码' value={this.state.password} onChange={(e)=>{this.handleChange(e)}} />
        </div>
        <div className='block'>
            {/* 通过value属性 和 onChange事件 让表单元素变成受控元素 */}
            <input name='isread' type="checkbox" checked={this.state.isread} onChange={(e)=>{this.handleChange(e)}} />勾选用户协议
        </div>
        <div className='block'>
            {/* input type=buttom 相当于提交表单 */}
            <input type="button" value='登录' onClick={()=>{this.login()}}/>
        </div>
      </div>
    );
  }
}

export default App;

 组件通信:

自定义属性:父向子传值

方法:子向父传值:本质就是一个回调函数

和vue都是写在父中导入的子组件上

//父组件向子组件传值: 父组件通过自定义属性传值给子组件, 子组件内部通过props获取值

//子组件向父组件传值: 父组件通过自定义属性传一个函数给子组件, 子组件内部通过props获取该函数并在合适的时机回调该函数完成传值.

//兄弟组件传值: 借助events库 先实例化一个公共的通信对象, 其中一个组件提前监听事件, 另一个兄弟组件在合适的时机触发事件并传值.

//跨组件传值: 借助createContext方法 先实例化一个公共的上下文通信对象, 外层组件通过Provider组件的value属性传值, 内层组件和上下文通信对象建立连接, 然后再通过this.context获取值.

父向子,子向父

兄弟组件通信:自带 events 不用装(尝试自己封装eventBus库)

使用之前要先建立eventBus文件,导入eventBus:::emit 触发事件传值,on监听,off 取消监听

emit触发传值

 

on监听,off 写在取消监听,性能优化

性能优化:取消监听。不是同一个函数名不能取消监听js中有体验:绑定函数名可以取消监听成功

 

跨组件通信:需要借助createContext方法,先实例化一个 utils文件夹下

React.createContext 实例化一个功能的通信上下文对象

创建上下文

MyContext.Provider 的value属性传值

app主文件。我的上下文

中间隔层文件

Class.contextType 和组件通信建立连接

类 构造函数

 

非嵌套组件间通信

1.利用二者共同父组件进行通信

2.使用自定义事件的方式

创建新项目typescript项目:::安装ts。

已有项目添加typescript则需要加配置项

npx create-react-app my-app --template typescript

tabbar底部导航:另类写法:主要用来子向父传递了索引,父判

import './App.scss';
// React应用的组件有两种创建方式: 函数式组件, 类组件
// rcc 创建class组件
// rsf 创建函数式组件
import React, { Component } from 'react';

import TopNav from '@/components/TopNav';
import Swiper from '@/components/Swiper';
import CateList from '@/components/CateList';
import Tabbar from '@/components/Tabbar';
import Cate from '@/components/Cate/Cate';

class App extends Component {
  constructor(props){
    super(props);
    this.state = { index:0 }
  }
  getIndex = (i)=>{
    this.setState({ index: i })
  }
  render() {
    return (
      <div>
        {/* 顶部导航 */}
        {/* 轮播图 */}
        {/* 分类导航 */}
        {
          this.state.index == 0 && 
            <>
              <TopNav />
              <Swiper />
              <CateList />
            </>
        }

        {
          this.state.index == 1 && <Cate />
        }


        {/* 底部导航 */}
        <Tabbar getIndex={this.getIndex} />

      </div>
    );
  }
}

export default App;

import React, { Component } from 'react';
import './index.scss'
class Tabbar extends Component {
    constructor(props) {
        // props和state的区别
        // 分别介绍两个技术的概念,先回答相同点,再回到不同点,最后总结一下(个人感悟,注意事项)

        // props是个对象,用来接收父组件传来的值,props默认是只读的(如果某个属性是引用类型,则引用数据的属性是可以修改)
        // state是个对象,用来定义组件自身的状态,可以通过setState来修改
        super(props)
        // 定义组件状态
        this.state = {
            tabs: [
                { text: '首页', img: '' },
                { text: '分类', img: '' },
                { text: '首页', img: '' },
                { text: '首页', img: '' },
            ],
            currentIndex: 0,
        }
    }
    handleClick(index) {
        // 回调父组件的方法
        this.props.getIndex(index)
        // this.state.currentIndex = index //这个写法可以保存数据到组件状态中,但是无法触发组件更新
        // setState会保存数据到组件状态中,同时会触发组件更新
        this.setState({ currentIndex: index }, () => {
            // 想要获取setState保存的最新状态值,必须在第二个参数的回调函数中获取(setState本身是异步的)
            // console.log('handleClick', this.state.currentIndex);
        })
    }
    render() {
        return (
            <div className='tabbar'>
                {
                    this.state.tabs.map((item, index) => {
                        return(
                            <div className={`btn ${this.state.currentIndex == index? 'active':''}`} key={index} onClick={()=>{this.handleClick(index)}}>
                                <img src={item.img} alt="" />
                                <div className='text'>{item.text}</div>
                            </div>
                        )
                    })
                }
            </div>
        );
    }
}

export default Tabbar;
.tabbar{
    position: fixed;
    bottom: 0;
    width: 100%;
    display: flex;
    justify-content: space-around;
    align-items: center;
    margin: 15px;
    border-top: 1px solid #ccc;
    .btn.active{
        color: red;
        font-weight: bold;
    }
}

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

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

相关文章

Unity中GPUInstance详解

为什么要用GPUInstance 在没有GPUInstance此技术之前&#xff0c;对于像草地、树木&#xff0c;割草游戏&#xff0c;它们往往是数据量很大&#xff0c;但同时又只存在微小的差别如位置、旋转、颜色等。如果像常规物体那样进行渲染&#xff0c;所使用的绘制指令必然很多…

3.3 向量与矩阵的范数

学习目标&#xff1a; 要学习向量与矩阵的范数&#xff0c;我会采取以下几个步骤&#xff1a; 了解基本概念&#xff1a;首先&#xff0c;我会了解向量和矩阵的范数的基本概念和定义&#xff0c;以及它们的性质和特点&#xff0c;这是理解和掌握范数的基础。 学习具体算法&am…

Nacos简介、基本概念、基本架构、安装部署

官网&#xff1a;https://nacos.io/zh-cn/ 官方文档&#xff1a; 什么是 Nacos Github&#xff1a;https://github.com/alibaba/nacos&#xff0c;阿里巴巴开源项目。 简介 什么是Nacos&#xff1f; Nacos&#xff1a;(Dynamic) Naming and Configuration Service&#xf…

空间相关性----地理探测器--学习记录

目录 相关教程--软件及数据准备 R语言数据分析1、R包、数据准备、GD综合代码2、分异及因子探测---q值 gd3、交互作用探测---评估因子gdinteract4、风险区探测--显著性--gdrisk()5、生态探测---交叉影响--gdeco() 数据准备注意&#xff1a;使用Arcgis首先创建.gdb&#xff08;本…

数学建模第二天:数学建模工具课之MATLAB绘图操作

目录 一、前言 二、二维绘图 1、曲线图、散点图plot 2、隐函数、显函数与参数方程的绘图 ①ezplot ②fplot 三、三维绘图 1、单曲线plot3 2、多曲线plot3 3、曲面 ①实曲面surf ②网格曲面mesh 四、特殊的二维、三维图 1、极坐标图polar 2、平面散点图scatter …

学网络安全都是一群什么人?

大家好呀&#xff0c;我是知了姐&#xff0c;又是一期学员故事栏目~ 3月下旬知了堂信安方向开新班&#xff0c;知了姐跟着去采访&#xff0c;了解到新学员们的求学故事&#xff0c;嘿你别说&#xff0c;虽然大家出身专业不同、经历背景不同&#xff0c;如今却在同一个地点相遇…

CAMX大气臭氧来源解析模拟

查看原文>>>基于CAMX大气臭氧来源解析模拟与臭氧成因分析实践技术应用 随着我国经济快速发展&#xff0c;我国面临着日益严重的大气污染问题。大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果&#xff0c;同时气象因素是控制大气污染的关键自然因…

【微信小程序】生命周期,插槽和组件间通信

一、组件的生命周期 1.1 组件全部的生命周期函数 小程序组件可用的全部生命周期如下表所示 生命周期函数参数描述说明created无在组件实例刚刚被创建时执行attached无在组件实例进入页面节点树时执行ready无在组件在视图层布局完成后执行moved无在组件实例被移动到节点树另一…

实战案例|聚焦攻击面管理,腾讯安全威胁情报守护头部券商资产安全

金融“活水”润泽千行百业&#xff0c;对金融客户来说&#xff0c;由于业务场景存在特殊性和复杂性&#xff0c;网络安全必然是一场“持久战”。如何在事前做好安全部署&#xff0c;构建威胁情报分析的防护体系至为重要&#xff0c;实现更为精准、高效的动态防御。 客户名片 …

Flink系列-8、Flink DataStream的简介和API开发

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 大数据系列文章目录 官方网址&#xff1a;https://flink.apache.org/ 学习资料&#xff1a;https://flink-learning.org.cn/ 目录 流处理的介…

开放式耳机真的比封闭式强很多吗?推荐几款主流的开放式耳机

​开放式耳机&#xff0c;顾名思义&#xff0c;就是通过骨头振动来传导声音的耳机。相比于传统耳机&#xff0c;它的声音传输更加开放&#xff0c;不会对耳膜造成压迫感&#xff0c;也不会对耳膜旁的内毛细胞造成损害。因此开放式耳机既是运动蓝牙耳机&#xff0c;又是音乐蓝牙…

MAC 通过 brew安装 redis 并且设置开机启动

一.安装 mysql 1.安装 mysql 1.安装 redis brew install redis2.查看 redis 安装目录 brew list redis 记住安装目录 3.启动 redis 进入到安装目录下面 cd /opt/homebrew/Cellar/redis/7.0.11 cd bin ./redis-server 二.设置开机启动 上面安装好之后,redis 虽然能正常…

个性化的客户服务策略(二)

继续上次的策略&#xff0c;今天我们继续分享接下来的几点提供更加个性化的客户服务的方法。 6&#xff09;利用社交媒体发挥自己的优势 请求进入社交媒体渠道原因有很多。例如&#xff0c;愤怒的客户可能会对帖子发送直接消息或评论&#xff0c;因为它感觉更直接&#xff0c;…

【刷题之路Ⅱ】LeetCode 3381.搜索旋转排序数组ⅠⅡ

【刷题之路Ⅱ】LeetCode 33&81.搜索旋转排序数组Ⅰ&Ⅱ 一、题目描述二、解题1、方法1——暴力法1.1、思路分析1.2、代码实现 2、方法2——二分法2.1、思路分析2.2、代码实现2.3、升级到81题2.3.1、改进思路分析2.3.1、改进代码实现 3、改进二分法3.1、思路分析3.2、代码…

STM32F407ZIT6 国产替代者NS32F407ZIT6 NS32F407ZGT6 软硬件通用 无需修改任何程序代码

NS32F407ZIT6 NS32F407ZGT6 器件基于高性能的 ARM Cortex-M4 32位 RISC 内核&#xff0c;工作频率高达 168MHz。 Cortex-M4 内核带有单精度浮点运算单元(FPU)&#xff0c;支持所有 ARM 单精度数据处理指令和数据类型。它还 具有一组DSP指令和提高应用安全性的一个存储器保护…

Windows环境下调试DAB-DETR与Deformable-DETR

先前都是在服务器上运行DETR的相关程序&#xff0c;服务器使用的是Linux&#xff0c;所以运行较为简单&#xff0c;但如果想要简单的debug的话就没必要使用服务器了&#xff0c;今天便来在Winodws环境下调试DETR类项目&#xff0c;这里以Deformable-DETR与DAB-DETR为例。 首先是…

深度测评全新大模型「天工」,这些AI体验太香了

ChatGPT火了后&#xff0c;很多人都在关注“国产ChatGPT”的名号究竟花落谁家。 事实上&#xff0c;名号不重要&#xff0c;体验才是王道。ChatGPT能够火成“史上增长最快的消费者应用”&#xff0c;关键在于把体验提升到了新层次。毕竟对于用户来说&#xff0c;并不清楚产品背…

【WSN定位】加权质心定位算法-Matlab代码

文章目录 1. 质心定位算法2. 加权质心定位算法3. 部分代码展示4. 效果图展示5. 资源获取说明 摘要&#xff1a;质心定位算法(Centroid Algorithm)是 Nirupama Bulusu等提出的一种无需测距的粗精度定位算法。质心算法的基本思路&#xff1a;利用未知节点通信范围内的所有锚节点进…

树莓派下编译 PyMiniRacer

文: fasiondog 因需要在树莓派&#xff08;及其其他各类派&#xff09;下使用 akshare&#xff0c;但 akshare 的依赖库 PyMiniRacer 缺少 arm64 架构的包&#xff08;该包已经不再维护&#xff09;&#xff0c;故在此记录下在 linux arm64 架构下编译 PyMiniRacer 的过程。有…

【微信小程序】 权限接口梳理以及代码实现

​ 1、权限接口说明 官方权限说明   部分接口需要经过用户授权统一才能调用。我们把这些接口按使用范围分成多个scope&#xff0c;用户选择对scope进行授权&#xff0c;当授权给一个scope之后&#xff0c;其对应的所有接口都可以直接使用。 此类接口调用时&#xff1a; 如…