总览

当我们在一个函数组件中使用一个字符串作为ref时,会产生"Function components cannot have string refs"错误。为了解决该错误,使用useRef()钩子来得到一个可变的ref对象,这样你就可以在组件中作为ref使用。

这里有个示例用来展示错误是如何发生的。

// App.js

export default function App() {
// A string ref has been found within a strict mode tree.
// ️ Function components cannot have string refs.
// We recommend using useRef() instead.
return (
<div>
<input type="text" id="message" ref="msg" />
</div>
);
}

上述代码片段的问题在于,我们使用了字符串作为ref

useRef

为了解决该错误,使用useRef钩子来获取可变的ref对象。

// App.js

import {useEffect, useRef} from 'react';

export default function App() {
const refContainer = useRef(null); useEffect(() => {
// ️ this is reference to input element
console.log(refContainer.current); refContainer.current.focus();
}, []); return (
<div>
<input type="text" id="message" ref={refContainer} />
</div>
);
}

useRef()钩子可以被传递一个初始值作为参数。该钩子返回一个可变的ref对象,其.current属性被初始化为传递的参数。

需要注意的是,我们必须访问ref对象上的current属性,以获得对我们设置了ref属性的input元素的访问。

当我们传递ref属性到元素上时,比如说,<input ref={myRef} /> 。React将ref对象上的.current属性设置为相应的DOM节点。

useRef钩子创建了一个普通的JavaScript对象,但在每次渲染时都给你相同的ref对象。换句话说,它几乎是一个带有.current属性的记忆化对象值。

不会重新渲染

应该注意的是,当你改变refcurrent属性的值时,不会引起重新渲染。

例如,一个ref不需要包含在useEffect钩子的依赖数组中,因为改变它的current属性不会引起重新渲染。

// App.js

import {useEffect, useRef} from 'react';

export default function App() {
const refContainer = useRef(null); const refCounter = useRef(0); useEffect(() => {
// ️ this is reference to input element
console.log(refContainer.current);
refContainer.current.focus(); // ️ incrementing ref value does not cause re-render
refCounter.current += 1;
console.log(refCounter.current);
}, []); return (
<div>
<input type="text" id="message" ref={refContainer} />
</div>
);
}

例子中的useEffect钩子只运行了2次,因为useRef在其内容发生变化时并没有通知我们。

改变对象的current属性并不会导致重新渲染。

React报错之Function components cannot have string refs的更多相关文章

  1. react 报错的堆栈处理

    react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...

  2. refiling失败报错Invalid function: org-preserve-local-variables

    refiling失败报错Invalid function: org-preserve-local-variables,原因: elc,不太清楚 解决办法: 删除org??目录下的elc文件 https ...

  3. mysql插入报错:java.sql.SQLException: Incorrect string value: '\xE6\x9D\xAD\xE5\xB7\x9E...' for column 'address' at row 1

    界面报错: 日志报错: java.sql.SQLException: Incorrect at com.mysql.cj.jdbc.exceptions.SQLError.createSQLExcep ...

  4. React报错之Expected `onClick` listener to be a function

    正文从这开始~ 总览 当我们为元素的onClick属性传递一个值,但是该值却不是函数时,会产生"Expected onClick listener to be a function" ...

  5. react报错this.setState is not a function

    当报错这个的时候就要看函数是否在行内绑定this,或者在constructor中绑定this. 我这里犯的错误的是虽然我在constructor中绑定了this,但是语法写的不正确. 错误示范: co ...

  6. react报错 TypeError: Cannot read property 'setState' of undefined

    代码如下: class test extends Component { constructor(props) { super(props); this.state = { liked: false ...

  7. React报错之Cannot find name

    正文从这开始~ .tsx扩展名 为了在React TypeScript中解决Cannot find name报错,我们需要在使用JSX文件时使用.tsx扩展名,在你的tsconfig.json文件中把 ...

  8. 开启bin-log日志mysql报错:This function has none of DETERMINISTIC, NO SQL解决办法

    开启bin-log日志mysql报错:This function has none of DETERMINISTIC, NO SQL解决办法: 创建存储过程时 出错信息: ERROR 1418 (HY ...

  9. gulp报错task function must be specified

    1.我npm安装了Browserify,tsify和vinyl-source-stream包,想要引用安装的插件,所以就走了引用插件的流程,修改了gulpfiles.js文件,引用流程完毕后,在终端g ...

  10. React报错 :browserHistory doesn't exist in react-router

    由于版本问题,React中history不可用 import { hashHistory } from 'react-router' 首先应该导入react-router-dom包: import { ...

随机推荐

  1. Ingress

    一.需求背景 固定对外提供服务采用了NodePort方式映射并固定了30001端口,但是,该端口默认范围是30000~32767,并且我们的web服务一般都是80.443端口对外,因此我们产生了如下几 ...

  2. 5_项目实战MyShop

    一. 网上商城 1.1 商城类别 B2B 商家对商家 B2C 商家对客户 C2C 客户对客户 O2O 线上线下相结合 1.2 商城常见模块 后台常见功能模块 商品管理 包括后台商品库存管理, 上货, ...

  3. a除于b

    a=eval(input()) b=eval(input()) if b!=0: print("{}".format(round(a/b,2))) else: print(&quo ...

  4. 使Squashfs可写的办法

    yiyi@yiyi-HP-Pavilion-Notebook:~/Applications/Office2016$ pwd /home/yiyi/Applications/Office2016 yiy ...

  5. # 如何在Windows下运行Linux程序

    如何在Windows下运行Linux程序 一.搭建 Linux 环境 1.1 安装 VMware Workstation https://www.aliyundrive.com/s/TvuMyFdTs ...

  6. ubuntu安装及使用

    ubuntu教程 一. Ubuntu简介 Ubuntu(乌班图)是一个基于Debian的以桌面应用为主的Linux操作系统,据说其名称来自非洲南部祖鲁语或科萨语的"ubuntu"一 ...

  7. 后端框架学习-----mybatis(4)

    文章目录 4.解决属性名和字段名不一致的问题 4.解决属性名和字段名不一致的问题 1.问题.数据库字段名和属性名不一致,导致查出的数据部分为空 2.resultMap(用于解决数据库表中的字段和属性) ...

  8. 八、指定节点pod运行在固定节点

    指定pod运行在固定节点 一.指定固定节点:Pod.spec.nodeName Pod.spec.nodeName 将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策 ...

  9. Java开发学习(三十九)----SpringBoot整合mybatis

    一.回顾Spring整合Mybatis Spring 整合 Mybatis 需要定义很多配置类 SpringConfig 配置类 导入 JdbcConfig 配置类 导入 MybatisConfig ...

  10. vue-axios删除操作

    <template> <div class="nav"> <input v-model="location" type=" ...