React高级指南(三)【Refs and the DOM】

本文介绍了React中Refs的基本概念及使用场景,包括如何为DOM元素和类组件添加Refs,并探讨了Refs在处理focus、触发动画及集成第三方库等方面的应用。

在常规的React数据流中,props是父组件与子组件交互的唯一方式。为了修改子元素,你需要用新的props去重新渲染子元素。然而,在少数情况下,你需要在常规数据流外强制修改子元素。被修改的子元素可以是React组件实例,也可以是DOM元素。在这种情况下,React提供了解决办法。

何时使用Refs

下面有一些恰当地使用refs的场景:

  • 处理focus、文本选择或者媒体播放
  • 触发强制动画
  • 集成第三方DOM库

如果可以通过声明式实现,就尽量避免使用refs。

例如,相比于在Dialog组件中暴露open()close()方法,最好传递isOpen属性。

为DOM元素添加Ref

React支持给任何组件添加特殊属性。ref属性接受回调函数,当组件安装(mounted)或者卸载(unmounted)之后,回调函数会立即执行。

当给HTML元素添加ref属性时,回调函数接受底层的DOM元素作为参数。例如,下面的代码使用ref函数来存储DOM节点的引用。

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.focus = this.focus.bind(this);
  }

  focus() {
    // 通过使用原生API,显式地聚焦text输入框
    this.textInput.focus();
  }

  render() {
    // 在实例中通过使用`ref`回调函数来存储text输入框的DOM元素引用(例如:this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />
      </div>
    );
  }
}

React将会在组件安装(mount)时,用DOM元素作为参数回调ref函数,在组件卸载(unmounts)时,使用null作为参数回调函数。

对class设置ref回调函数是访问DOM元素的一种常见方法。首选的方式就是像上面的代码一样,对ref设置回调函数。还有更简洁的方式:ref={input => this.textInput = input}

为类(Class)组件添加Ref

为用类(class)声明的自定义组件设置ref属性时,ref回调函数收到的参数是安装(mounted)的组件实例。例如,如果我们想包装CustomTextInput组件,实现组件在mounted后立即点击的效果:

class AutoFocusTextInput extends React.Component {
  componentDidMount() {
    this.textInput.focus();
  }

  render() {
    return (
      <CustomTextInput
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

需要注意的是,这种方法仅对以类(class)声明的CustomTextInput有效。

class CustomTextInput extends React.Component {
  // ...
}

Refs与函数式Components

你不能在函数式组件上使用ref因为函数式组件不会创建实例:

function MyFunctionalComponent() {
  return <input />;
}

class Parent extends React.Component {
  render() {
    // 无效!
    return (
      <MyFunctionalComponent
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

如果你需要使用ref,你需要将组件转化成class组件,就像需要生命周期函数或者state那样。

然而你可以在函数式组件内部使用ref来引用一个DOM元素或者class组件。

function CustomTextInput(props) {
  // textInput must be declared here so the ref callback can refer to it
  let textInput = null;

  function handleClick() {
    textInput.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={(input) => { textInput = input; }} />
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}

不要滥用Refs

在你应用中,你可能会倾向于使用ref使得”事件发生”。如果这种情况下,花一点时间仔细考虑一下在组件层次结构中哪些地方需要state。通常情况下,应该在层次结构中较高级别中拥有state。有关这方面的实例参阅提升state

旧版API: String类型的Refs

如果你之前使用过React,你可能了解过之前的API:string类型的ref属性。类似于textInput,可以通过this.refs.textInput访问DOM节点。我们不建议使用,因为string类型的ref存在问题。已经过时了,可能会在未来的版本是移除。如果你目前还在使用this.refs.textInput这种方式访问refs,我们建议用回调函数的方式代替。

注意

如果ref以内联函数的方式定义,在update期间会被调用两次,第一次参数是null,之后参数是DOM元素。这是因为在每次渲染中都会创建一个新的函数实例。因此,React需要清理旧的ref并且设置新的。通过将ref的回调函数定义成类的绑定函数的方式可以避免上述问题,但是在大多数例子中这都不是很重要。

本系统采用Python编程语言中的Flask框架作为基础架构,实现了一个面向二手商品交易的网络平台。该平台具备完整的前端展示与后端管理功能,适合用作学术研究、课程作业或个人技术能力训练的实际案例。Flask作为一种简洁高效的Web开发框架,能够以模块化方式支持网站功能的快速搭建。在本系统中,Flask承担了核心服务端的角色,主要完成请求响应处理、数据运算及业务流程控制等任务。 开发工具选用PyCharm集成环境。这款由JetBrains推出的Python专用编辑器集成了智能代码提示、错误检测、程序调试与自动化测试等多种辅助功能,显著提升了软件编写与维护的效率。通过该环境,开发者可便捷地进行项目组织与问题排查。 数据存储部分采用MySQL关系型数据库管理系统,用于保存会员资料、产品信息及订单历史等内容。MySQL具备良好的稳定性和处理性能,常被各类网络服务所采用。在Flask体系内,一般会配合SQLAlchemy这一对象关系映射工具使用,使得开发者能够通过Python类对象直接管理数据实体,避免手动编写结构化查询语句。 缓存服务由Redis内存数据库提供支持。Redis是一种支持持久化存储的开放源代码内存键值存储系统,可作为高速缓存、临时数据库或消息代理使用。在本系统中,Redis可能用于暂存高频访问的商品内容、用户登录状态等动态信息,从而加快数据获取速度,降低主数据库的查询负载。 项目归档文件“Python_Flask_ershou-master”预计包含以下关键组成部分: 1. 应用主程序(app.py):包含Flask应用初始化代码及请求路径映射规则。 2. 数据模型定义(models.py):通过SQLAlchemy声明与数据库表对应的类结构。 3. 视图控制器(views.py):包含处理各类网络请求并生成回复的业务函数,涵盖账户管理、商品展示、订单处理等操作。 4. 页面模板目录(templates):存储用于动态生成网页的HTML模板文件。 5. 静态资源目录(static):存放层叠样式表、客户端脚本及图像等固定资源。 6. 依赖清单(requirements.txt):记录项目运行所需的所有第方Python库及其版本号,便于环境重建。 7. 参数配置(config.py):集中设置数据库连接参数、缓存服务器地址等运行配置。 此外,项目还可能包含自动化测试用例、数据库结构迁移工具以及运行部署相关文档。通过构建此系统,开发者能够系统掌握Flask框架的实际运用,理解用户身份验证、访问控制、数据持久化、界面动态生成等网络应用关键技术,同时熟悉MySQL数据库运维与Redis缓存机制的应用方法。对于入门阶段的学习者而言,该系统可作为综合性的实践训练载体,有效促进Python网络编程技能的提升。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值