You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unless you’re doing lazy initialization, avoid setting refs during rendering — this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects.
constRenderCounter=()=>{constcounter=useRef(0);// counter.current的值可能增加不止一次counter.current=counter.current+1;return(<h1>{`The component has been re-rendered ${counter.current} times`}</h1>);}
Unless you’re doing lazy initialization, avoid setting refs during rendering — this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects.
React Hook useEffect has an unnecessary dependency: 'ref.current'. Either exclude it or remove the dependency array. Mutable values like 'ref.current' aren't valid dependencies because mutating them doesn't re-render the component react-hooks/exhaustive-deps
useRef
一、动机
函数组件每次渲染都会被执行,函数内部的局部变量一般会重新创建,利用
useRef
可以访问上次渲染的变量,类似类组件的实例变量
效果。1.2 函数组件使用
React.createRef
不行吗?可以,但不是最佳实践。
React.createRef
主要解决class
组件访问DOM元素问题,并且最佳实践是在组件周期内只创建一次(一般在构造函数里创建)。如果在函数组件内使用React.createRef
会造成每次render
都会调用React.createRef
:二、使用
2.1 基本语法
见文档
useRef
返回值都不变;ref.current
发生变化并不会造成re-render
;ref.current
发生变化应该作为Side Effect
(因为它会影响下次渲染),所以不应该在render
阶段更新current
属性。2.2
不可以
在render
里更新ref.current
值在Is there something like instance variables提到:
在
render
里更新refs
导致什么问题呢?在异步渲染里
render
阶段可能会多次执行。2.3
可以
在render
里更新ref.current
值同样也是在Is there something like instance variables提到的:
为啥
lazy initialization
却可以在render
里更新ref.current
值?这个跟
useRef
懒初始化的实现方案有关。本质上只要保证每次
render
不会造成意外效果,都可以在render阶段
更新ref.current
。但最好别这样,容易造成问题,useRef
懒初始化毕竟是个特殊的例外。2.4
ref.current
不可以
作为其他hooks(useMemo
,useCallback
,useEffect
)依赖项ref.current
的值发生变更并不会造成re-render
, Reactjs并不会跟踪ref.current
的变化。本例子中当点击[Add]两次后
#1 uesEffect
就不会再执行了。原因分析:
依赖项判断是在
render
阶段判断的,发生在在ref.current
更新之前,而useEffect
的effect函数执行在渲染之后。首次无脑执行,所以输出:
并且此时
ref.current
为null
,所以#1 uesEffect
相当于useEffect(() => console.log('num 1'), [null])
此时
ref.current
值为<h1>Num: 0<h1>
,所以#1 uesEffect
的依赖项发生变化,最终输出:此时
#1 uesEffect
相当于useEffect(() => console.log('num 1'), [<h1>Num: 0<h1>])
此时
ref.current
值为<h1>Num: 1<h1>
,所以#1 uesEffect
的依赖项没有发生变化,故#1 uesEffect
的effect函数不会被执行,最终输出:如果将
ref.current
作为依赖项,eslint-plugin-react-hooks
也会报警提示的:2.5
ref
作为其他hooks(useMemo
,useCallback
,useEffect
)依赖项ref
是不变的,没必要作为其他hooks依赖。但是添加也无妨,有时候为了更明确表达依赖项也吧ref
写入依赖数组里。三、什么时候使用?
四、原理
本质上是记忆hook,但也可作为data hook,可以简单的用
useState
模拟useRef
:4.1 如何选择
useState
和useRef
?useState
和useRef
都可以作为data hook,那什么时候使用useState
,什么时候使用useRef
呢?原则:
4.2 在生命周期哪个阶段处理?
参考
The text was updated successfully, but these errors were encountered: