useRef 与 useState 的区别
一般在使用react-hook的时候,我们用到最多的就是定义变量,以及对应的修改变量
下面是一个最基本的 react-hook 应用程序
const Home = () => { const [username, setUserName] = useState(''); return ( <input value={username} onChange={(e) => setUserName(e.target.value)} /> ) }
以上并不是以使用useState的方式来进行对useRef的衬托,两者功能是不同的,只是便于区分
但是如果我想让浏览器渲染的时候,让他的次数自增,这样就会有一些意想不到的隐患…
如下代码所示,当我使用 useEffect 钩子进行input值渲染的时候,他的状态会发生改变,然后又会重新渲染,状态又重新改变,于是就这样无限循环下去…
const Home = () => { const [username, setUserName] = useState(''); useEffect(() => { // useEffect 页面渲染时所调用的钩子 setUserName(username => username + 1); }, [username]) return ( <input value={username} // 循环...循环...循环 /> ) }
ReactuseEffect钩子改变状态再次循环yes
useRef 的 用法以及特性
介绍: useRef 是一个 React Hook,它能让你引用一个不需要渲染的值。
使用 useRef 可以返回一个只有一个属性的对象: current,从一开始,他会是你传递的 initial Value, 之后,如果你需要,可以修改它(ref.current), 如果或他是一个需要你渲染的对象,那么你将不应该去修改它。
这可能会让你想起 useState,但是useRef是可变的, useRef值不会触发react渲染机制, 因为它本身就是一个再普通不过的javascript对象。这意味着 ref 是存储一些不影响组件视图输出的信息的完美选择!
官方文档注意:
除了 初始化 外不要在渲染期间写入 或者读取 ref.current。这会使你的组件的行为不可预测。
在严格模式下,React 将会 调用两次组件方法,这是为了 帮助你发现意外的问题。这只是开发模式下的行为,不影响生产模式。每个 ref 对象将会创建两次,但是其中一个版本将被丢弃。如果你的组件函数是纯的(应该如此),这不会影响其行为。
useRef(initialValue)
在你组件的顶层调用 useRef 声明一个 ref。
import React, { useRef } from 'react' const useRefTest = () => { const pNum = useRef(0) ... }
useRef 会返回单个 current
current: 0
通过使用 ref,你可以确保:
- 你可以在重新渲染之间 存储信息(不像是普通对象,每次渲染都会重置)。
- 改变它 不会触发重新渲染(不像是 state 变量,会触发重新渲染)。
- 对于你的组件的每个副本来说,这些信息都是本地的(不像是外面的变量,是共享的)。
通过 ref 操作 DOM
使用 ref 操作 DOM 是非常常见的。React 内置了对它的支持。
首先,声明一个 initial value 为 null 的 ref 对象
import React, { useRef } from 'react' const test = () => { const defaultDom = useRef(null) }
然后将你的 ref 对象作为 ref 属性传递给你想要操作的 DOM 节点的 JSX
import React, { useRef } from 'react' const test = () => { const defaultDom = useRef(null) return ( <> <input ref={defaultDom} /> <button onClick={handleClick}>foucs the input!</button> </> ) }
当 React 创建 DOM 节点并将其渲染到屏幕时,React 将会把 DOM 节点设置为你的 ref 对象的 current 属性。现在你可以访问 的 DOM 节点,并且可以调用类似于 focus() 的方法 (获取input输入框的焦点):
const handleClick = () => { defaultDom.current.focus() }