我对useRef的功能有一个疑问。我们知道useEffect会在渲染后更新值,useRef不会导致重新渲染。值更新晚了一个周期所以当我们试图在DOM useRef变量中显示任何值时,它显示的是之前的值这成为useRef的主要用例但update count如何正常工作,显示当前值而不晚了一个周期?
import React from "react";
import "./App.css";
import { useEffect, useState, useRef } from "react";
function App(){
const count = useRef(0);
const text = useRef("");
const [inputValue, setInputValue] = useState("");
useEffect(() => {
text.current = inputValue;
count.current = count.current + 1;
});
return (
<>
<input type="text" value={inputValue} onChange={(e)=>setInputValue(e.target.value)} />
<h1>Render Count: {count.current}</h1> //displays 1 after re-rende
<h1>{text.current}</h1> //displays "" after re-render
</>
);
}
count变量以当前值运行,而不是延迟一个周期。也就是说,在我键入一个字母"a"之后;在文本框中输入计数。电流从0变为1,并显示1但文本。当前显示前一个值,即"而不是"为什么?
计数也应该运行1个周期后,应该在第二次重新渲染后显示1,而不是第一次重新渲染。
因为第一次渲染组件时,counter.current
的值变成了1
,而text.current
的值仍然是""
。如果你想让它们同步,不要在第一次调用useEffect
回调时增加counter.current
的值,因为当时input
字段没有发生任何变化。
定义一个useRef
来控制组件是mounted还是isUpdated,如下所示:
const isMounted = useRef(false);
然后改变useEffect
回调:
useEffect(() => {
if(isMounted.current){
text.current = inputValue;
count.current = count.current + 1;
}
else{
isMounted.current = true;
}
});
这次你可以看到,counter.current
和text.current
都在当前更改的后面,并且它们是同步在一起的。
我认为根核心是以下两点:
- 首先,
useEffect
钩子在渲染或重新渲染后被触发,因此useEffect
钩子中的代码将稍后更新 - 文本。current = inputValue表示对
inputValue
有引用,所以当inputValue
有最新的值时,text.current
同时有新的值。此进程发生在onChange
事件中,useEffect
事件之前。
这导致text.current
有最新值,count.current
没有