当前位置: 首页 > article >正文

react18中的受控与非受控组件及ref的使用

受控与非受控组件

  • 受控组件,基于修改 state 的值,修改组件内部的状态,来实现页面的更新,推荐使用

  • 非受控组件,基于 ref 获取 dom 的值,来实现页面的更新,不推荐使用,偶尔特殊的场景会使用

    • 给需要获取的元素设置 ref=“xxx”,后期基于 this.refs.xxx 去获取相应的 dom 元素(不推荐使用)
    <div>
      <h2 className="title" ref="box2">温馨提示</h2>
    </div>
    

    获取:this.refs.box2

    • 把 ref 设置为函数的方式,推荐使用
    <div>
          <h2 className="title" ref={(x) => (this.box2 = x)}>
            温馨提示
          </h2>
        </div>
    

    获取:this.box2.style.color = "green";

    • 基于 createRef 创建的 ref,推荐使用
      在这里插入图片描述
componentDidMount() {
    console.log("ClassComp componentDidMount");
    // const dom = document.querySelector(".title");
    // console.log("🚀 ~ ClassComp ~ componentDidMount ~ dom:", dom);
    // dom.style.color = "red";
    // const dom = this.refs.titleBox;
    console.log("🚀 ~ ClassComp ~ componentDidMount ~ dom:", this.box2);
    // dom.style.color = "green";
    this.box2.style.color = "green";
  }

原理:render 函数执行的时候,获取 vdom 的 ref 属性,然后根据 ref 的值去 dom 树中找对应的节点

  • 如果是字符串,则会给 this.refs 增加一个这样的成员,成员值就是当前的 dom 节点
  • 如果是函数,则直接调用这个函数,并将当前 dom 节点作为参数传递进去,我们一般都是直接把这个 dom 挂在到实例的某个属性上

组件和 dom 元素上的 ref

  • 组件上:ref={(x) => (this.box2 = x)} 获取的是组件实例
  • 元素上:ref=“box2” 获取的是 dom 节点
import { Component, createRef } from "react";

class Child1 extends Component {
  render() {
    return <h2 className="title">标题111</h2>;
  }
}
class Child2 extends Component {
  render() {
    return <h2 className="title">标题222</h2>;
  }
}

class ClassComp extends Component {
  box3 = createRef();
  render() {
    return (
      <div>
        <h2 className="title" ref={this.box3}>
          温馨提示
        </h2>
        <Child1 ref={(x) => (this.child1 = x)} />
        <Child2 ref={(x) => (this.child2 = x)} />
        <input type="text" ref={(x) => (this.input = x)} />
      </div>
    );
  }
  componentDidMount() {
    console.log(this.child1);
    console.log(this.child2);
    console.log(this.input);
  }
}
export default ClassComp;

在这里插入图片描述

  • 在函数组件上使用函数的方式获取 ref,会报错,正确的方式是使用 forwardRef 来实现 ref 的转发,获取函数子组件的 dom 节点
import { Component, createRef, forwardRef } from "react";

class Child1 extends Component {
  render() {
    return <h2 className="title">标题111</h2>;
  }
}
const Child2 = forwardRef(function (props, ref) {
  return (
    <h2 className="title" ref={ref}>
      标题222
    </h2>
  );
});

class ClassComp extends Component {
  box3 = createRef();
  render() {
    return (
      <div>
        <h2 className="title" ref={this.box3}>
          温馨提示
        </h2>
        <Child1 ref={(x) => (this.child1 = x)} />
        <Child2 ref={(x) => (this.child2 = x)} />
        <input type="text" ref={(x) => (this.input = x)} />
      </div>
    );
  }
  componentDidMount() {
    console.log(this.child1);
    console.log(this.child2);
    console.log(this.input);
  }
}
export default ClassComp;

在这里插入图片描述


http://www.kler.cn/a/369329.html

相关文章:

  • 数据结构_二叉树
  • 【福建医科大学附属第一医院-注册安全分析报告】
  • 自定义鼠标事件在拖拽中的使用
  • 从0到1学习node.js(express模块)
  • 计算机网络-CSMA/CD协议笔记及“争用期”的理解
  • 【MyBatis源码】SqlSessionFactoryBuilder源码分析
  • 配置 SSH 无需密码连接服务器及为 IP 指定自定义域名
  • arthas使用 笔记
  • 2025选题|基于Hadoop的物品租赁系统的设计与实现
  • windows 训练yolov8官方数据集
  • SpringBoot poi-tl通过模板占位符生成word文件
  • 奥哲与中建三局集团有限公司战略签约
  • 美畅物联丨视频上云网关如何配置上级联网云平台
  • nacos安装与配置
  • 存储引用服务(OSS)Minio 环境搭建
  • 最新版的 Git+VS Code同步版本管理实践
  • 运维面试汇总
  • [JAVAEE] 面试题(一) - 锁策略, synchronized的详细介绍
  • 标题点击可跳转网页
  • 【32】C++流
  • ETLCloud+Doris组合:数据集成,更简单更高效
  • Linux系统基础-进程间通信(5)_模拟实现命名管道和共享内存
  • 【ubuntu18.04】ubuntu18.04 编译LightGBM操作说明
  • 大众点评 web mtgsig 1.2分析
  • AI跟踪报道第62期-本周AI新闻: 微软推出Copilot的AI Agent和Computer Control
  • 【学术会议投稿】Imagen:重塑图像生成领域的革命性突破