React高级特性之受控和非受控组件

news2024/11/28 9:37:41

一、受控组件

受控组件:input框自己的状态被React组件状态控制

// 类组件引入React
import React from 'react'

class InputComponent extends React.Component{
  state = {
    message: 'zm66666'
  }
  changeHandler = (e) => {
    this.setState({
      message: e.target.value
    })
  }
  render () {
    // 使用状态
    return (
      <div>
        {/* 绑定value 绑定事件 */}
        <input type='text' value={this.state.message} onChange={this.changeHandler} />
      </div>
    )
  }
}

function App () {
  return (
    <div className="App">
      <InputComponent/>
    </div>
  )
}

export default App


// 受控组件:input框自己的状态被React组件状态控制

// 1. 在组件的state中声明一个组件的状态数据
// 2. 将状态数据设置为input标签元素的value属性的值
// 3. 为input添加change事件,在事件处理程序中,通过事件对象e获取到当前文本框的值(即用户当前输入的值)
// 4. 调用setState方法,将文本框的值作为state状态的最新值
// 受控组件

import React, { FC, useState, ChangeEvent } from 'react'
// import type { ChangeEvent } from 'react'

const FormDemo: FC = () => {

  // input
  const [text, setText] = useState<string>('input')
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setText(event.target.value)
  }

  // textarea
  const [text2, setText2] = useState<string>('textarea')
  const handleChange2 = (event: ChangeEvent<HTMLTextAreaElement>) => {
    setText2(event.target.value)
  }
  const getHtml = () => {
    return { __html: text2.replaceAll('\n', '<br>') }
  }

  // radio
  const [gender, setGender] = useState<string>('male')
  const handleChange3 = (event: ChangeEvent<HTMLInputElement>) => {
    setGender(event.target.value)
  }

  // checkbox
  // const [checked, setChecked] = useState(false)
  // const handleChange4 = (event: ChangeEvent<HTMLInputElement>) => {
  //   setChecked(!checked)
  // }

  // checkbox组
  const [selectedFruitList, setselectedFruitList] = useState<string[]>([])
  const handleChange5 = (event: ChangeEvent<HTMLInputElement>) => {
    const fruit = event.target.value
    if (selectedFruitList.includes(fruit)) {
      setselectedFruitList(selectedFruitList.filter(f => {
        if (f === fruit) return false
        return true
      }))
    } else {
      setselectedFruitList(selectedFruitList.concat(fruit))
    }
  }

  // select
  const [lang, setLang] = useState<string>('js')
  const handleChange6 = (event: ChangeEvent<HTMLSelectElement>) => {
    setLang(event.target.value)
  }


  return (
    <>
      <div>
        FormDemo:
        <div>
          <span>input:</span>
          <input type="text" value={text} onChange={handleChange}/>
          <button onClick={() => console.log(text)}>打印</button>
          <button onClick={() => setText('66666666')}>set</button>
        </div>
        <div>
          <span>textarea:</span>
          <textarea value={text2} onChange={handleChange2}/>
          <p dangerouslySetInnerHTML={getHtml()}></p>
        </div>
        <div>
          <span>radio:</span>
          <label htmlFor="radio1"></label>
          <input type="radio" value='male' name='gender' id='radio1' onChange={handleChange3} checked={gender === 'male'}/>
          <label htmlFor="radio2"></label>
          <input type="radio" value='female' name='gender' id='radio2' onChange={handleChange3} checked={gender === 'female'}/>
          <button onClick={() => console.log(gender)}>打印{gender}</button>
        </div>
        {/* <div>
          <span>checkbox:</span> 
          <label htmlFor="checkbox1">选中</label>
          <input type="checkbox" id='checkbox' checked={checked} onChange={handleChange4}/>{checked.toString()}
        </div> */}
        <div>
          <span>checkbox组:</span> 
          <label htmlFor="checkbox1">苹果</label>
          <input type="checkbox" id='checkbox1' value='apple' checked={selectedFruitList.includes('apple')} onChange={handleChange5}/>
          <label htmlFor="checkbox2">橙子</label>
          <input type="checkbox" id='checkbox2' value='orange' checked={selectedFruitList.includes('orange')} onChange={handleChange5}/>
          <label htmlFor="checkbox3">香蕉</label>
          <input type="checkbox" id='checkbox3' value='banana' checked={selectedFruitList.includes('banana')} onChange={handleChange5}/>
          {JSON.stringify(selectedFruitList)}
        </div>
        <div>
          <span>select:</span>
          <select value={lang} onChange={handleChange6}>
            <option value='java'>java</option>
            <option value='js'>js</option>
            <option value='php'>php</option>
          </select>
        </div>
      </div>
    </>
  )
}


export default FormDemo

// 受控组件 vs 非受控组件
// 受控组件: 值同步到state, 使用value属性
// 非受控组件: 值不同步state, 使用defaultValue属性
// react推荐使用受控组件, 看似麻烦,但是 更加可控

二、非受控组件

// 类组件引入React createRef
import React, { createRef } from 'react'

class InputComponent extends React.Component{
  // 使用createRef产生一个存放dom的对象容器
  msgRef = createRef()

  changeHandler = () => {
    console.log(this.msgRef.current)
    console.log(this.msgRef.current.value)
  }

  render () {
    // 使用状态
    return (
      <div>
        {/* ref绑定 获取真实dom */}
        <input ref={this.msgRef} />
        <button onClick={this.changeHandler}>click</button>
      </div>
    )
  }
}

function App () {
  return (
    <div className="App">
      <InputComponent/>
    </div>
  )
}

export default App


// 非受控组件: 
// 通过手动操作dom的方式获取文本框的值
// 文本框的状态不受react组件的state中的状态控制
// 直接通过原生dom获取输入框的值

// 1.导入createRef 函数
// 2.调用createRef函数,创建一个ref对象,存储到名为msgRef的实例属性中
// 3.为input添加ref属性,值为msgRef
// 4.在按钮的事件处理程序中,通过msgRef.current即可拿到input对应的dom元素,
// 而其中msgRef.current.value拿到的就是文本框的值
import React from 'react'

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            name: '双越',
            flag: true,
        }
        this.nameInputRef = React.createRef() // 创建 ref
        this.fileInputRef = React.createRef()
    }
    render() {
        // // input defaultValue
        // return <div>
        //     {/* 使用 defaultValue 而不是 value ,使用 ref */}
        //     <input defaultValue={this.state.name} ref={this.nameInputRef}/>
        //     {/* state 并不会随着改变 */}
        //     <span>state.name: {this.state.name}</span>
        //     <br/>
        //     <button onClick={this.alertName}>alert name</button>
        // </div>

        // // checkbox defaultChecked
        // return <div>
        //     <input
        //         type="checkbox"
        //         defaultChecked={this.state.flag}
        //     />
        // </div>

        // file
        return <div>
            <input type="file" ref={this.fileInputRef}/> // 获取上传问卷 要使用非受控组件!!!!!!!!
            <button onClick={this.alertFile}>alert file</button>
        </div>

    }
    alertName = () => {
        const elem = this.nameInputRef.current // 通过 ref 获取 DOM 节点
        alert(elem.value) // 不是 this.state.name
    }
    alertFile = () => {
        const elem = this.fileInputRef.current // 通过 ref 获取 DOM 节点
        alert(elem.files[0].name)
    }
}

export default App

三、总结

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

第五十八章 学习常用技能 - 查看查询缓存

文章目录 第五十八章 学习常用技能 - 查看查询缓存查看查询缓存建立索引使用调谐表工具 第五十八章 学习常用技能 - 查看查询缓存 查看查询缓存 对于 SQL&#xff08;用作嵌入式 SQL 时除外&#xff09;&#xff0c;系统会生成可重用代码来访问数据&#xff0c;并将该代码放置…

二手安捷伦E9323A射频传感器

安捷伦E9323A射频传感器 E9323A 是 Agilent 使用的 6 GHz 0.1 瓦射频传感器。电子测试设备传感器测量波形的功率&#xff0c;例如多音和调制射频 (RF) 波形。传感器使用二极管检测器收集高度精确的调制测量值。 5 MHz 视频带宽&#xff0c;非常适合 W-CDMA 和 cdma2000 应用 通…

机器视觉知识讲的深不如讲的透

我深思这个话题&#xff0c;大家来培训&#xff0c;其实培训机构也很痛苦&#xff0c;每个热掌握的参差不齐&#xff0c;你说他不会吧&#xff0c;会一点电气&#xff0c;你说他会吧&#xff0c;会一点Opencv&#xff0c;会一点visionpro,会一点Visionmaster,会一点Halcon。好像…

LangChain与大型语言模型(LLMs)应用基础教程:神奇的Agent

原文&#xff1a;LangChain与大型语言模型(LLMs)应用基础教程:神奇的Agent-CSDN博客 LangChain是大型语言模型(LLM)的应用框架,LangChain可以直接与 OpenAI 的 text-davinci-003、gpt-3.5-turbo 模型以及 Hugging Face 的各种开源语言模如 Google 的 flan-t5等模型集成。通过使…

c++11新增特性

目录 新增容器 ​编辑 新增语法 变量类型推导 auto 存储类型 分类 自动存储类型 静态存储类型 寄存器存储类型 外部链接存储类型 decltype typeid(c98) type_info { }初始化 initializer_list 介绍 使用 模拟实现 nullptr final与override 范围for 右值…

PVIT:利用位置信息增强多模态模型理解用户意图的能力

论文链接&#xff1a; https://arxiv.org/abs/2308.13437 代码链接&#xff1a; https://github.com/PVIT-official/PVIT Demo&#xff1a; https://huggingface.co/spaces/PVIT/pvit 引言 随着ChatGPT等语言大模型的走红&#xff0c;越来越多人尝试探索为语言大模型赋予视觉能…

中断机制-通过AtomicBoolean实现线程中断停止

通过AutomicBoolean package com.nanjing.gulimall.zhouyimo.test;import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean;/*** author zhou* version 1.0* date 2023/10/15 2:42 下午*/ public class InterruptDemo2 {static AtomicBoole…

分治算法——快排 | 归并思想

文章目录 一、快排思想1. leetcode75. 颜色分类2. leetcode912. 排序数组3. leetcode215. 数组中的第K个最大元素4. leetcode面试题17.14. 最小K个数 二、归并思想1. leetcode912. 排序数组2. leetcodeLCR 170. 交易逆序对的总数3. 计算右侧小于当前元素的个数4. 翻转对 一、快…

GBJ3510-ASEMI电源控制柜专用GBJ3510

编辑&#xff1a;ll GBJ3510-ASEMI电源控制柜专用GBJ3510 型号&#xff1a;GBJ3510 品牌&#xff1a;ASEMI 芯片个数&#xff1a;4 封装&#xff1a;GBJ-4 恢复时间&#xff1a;&#xff1e;50ns 工作温度&#xff1a;-55C~150C 浪涌电流&#xff1a;350A 正向电流&am…

iWall:支持自定义的Mac动态壁纸软件

iWall Mac是一款动态壁纸软件&#xff0c;它可以使用任何格式的漂亮视频&#xff08;无须转换&#xff09;、图片、动画、Flash、gif、swf、程序、网页、网站做为您的动态壁纸、动态桌面&#xff0c;并且可以进行交互。 这款软件功能多、使用简单、体积小巧、不占用资源、运行…

Java每日笔试题错题分析(5)

Java每日笔试题错题分析&#xff08;5&#xff09; 一、错题知识点前瞻第1题第2题第3题第4题第5题第6题第7题 二、错题展示及其解析第1题第2题第3题第4题第5题第6题第7题 一、错题知识点前瞻 第1题 数组的初始化 数组的初始化有两种&#xff0c;分为静态初始化和动态初始化 静…

ai_drive67_基于不确定性的多视图决策融合

论文链接&#xff1a;https://openreview.net/forum?idOOsR8BzCnl5 https://arxiv.org/abs/2102.02051 代码链接&#xff1a;https://github.com/hanmenghan/TMC Zongbo Han, Changqing Zhang, Huazhu Fu, Joey Tianyi Zhou, Trusted Multi-View Classification, Internatio…

动态内存管理改造简易通讯录

动态通讯录 本章内容基于上章内容实现&#xff0c;具体情况若有不清楚&#xff0c;请先查看上一篇文章。 动态通讯录实现了&#xff0c;动态开辟&#xff0c;如果存放满了&#xff0c;再开辟空间进行存储&#xff0c;相对静态更方便一些。 动态通讯录需要改造的地方 我们基于…

Python--比较运算符

比较运算符 特别注意&#xff1a;当我们使用比较运算符对两个变量进行比较时&#xff0c;其返回一个布尔类型的值。 案例&#xff1a;两个数大小的比较 num1 10 num2 20 print(num1 > num2) # False print(num1 < num2) # True print(num1 > num2) # False print…

使用免费云服务器体验

免费的才是最贵的 谈谈使用【三*丰*云*免*费*服务器】的超级后悔体验 你以为开通了就永久免费了&#xff1f;怎么可能&#xff01;&#xff01;&#xff01; 使用方法 第一步&#xff1a;注册&#xff0c;实名认证 实名认证收费0.7 此时可以使用24小时&#xff0c;到期自动…

AI影像修复及图像超分辨率

AI图像修复软件主要包含人脸修复、图像超分等功能。人脸修复功能主要对图像上的人脸进行识别和修复&#xff0c;从模糊、缺损、噪声图像中恢复高质量人脸图像。图像超分功能主要对图像进行超分辨率重建&#xff0c;将低分辨率图像处理为高分辨率图像。 链接&#xff1a;https:…

Linux:基础命令

Linux&#xff1a;基础命令 0. Linux的目录结构1. Linux命令基础格式2. ls命令2.1 隐藏文件、文件夹 3. 相对和绝对路径3.1 特殊路径符 4. mkdir命令4.1 mkdir -p 选项 5. touch 创建文件6. cat命令 查看文件内容 0. Linux的目录结构 /&#xff0c;根目录是最顶级的目录了Linux…

【java学习—七】关键字super(32)

文章目录 1. 功能2. 代码中理解3. super调用父类构造器3.1. 结论一证明3.2. 结论二证明 4. this和super的区别 1. 功能 在 Java 类中使用 super 来调用父类中的指定操作&#xff1a; &#xff08;1&#xff09;super 可用于访问父类中定义的属性 &#xff08;2&#xff09;sup…

unity的脚本执行顺序问题

当一个物体同时挂载有多个脚本时&#xff0c;谁会先执行呢&#xff1f; 猜想&#xff1a;Test2在Test1的上面应该会先执行吧&#xff01; 结果&#xff1a;Test1先执行 如果你想要某一个脚本先执行&#xff0c;可以使用Awake方法 执行顺序 是先把所以脚本的Awake执行完&a…

【Transformer系列】深入浅出理解ViT(Vision Transformer)网络模型

一、参考资料 极智AI | 详解 ViT 算法实现 MobileViT模型简介 ECCV 2022丨力压苹果MobileViT&#xff0c;这个轻量级视觉模型新架构火了 ECCV 2022丨轻量级模型架构火了&#xff0c;力压苹果MobileViT&#xff08;附代码和论文下载&#xff09; 再读VIT&#xff0c;还有多少细…