当前位置:网站首页>Understanding useref is enough
Understanding useref is enough
2022-07-26 11:49:00 【sunilwang】
Author's brief introduction
Wang Shu : One can write Node.js The whole stack of engineers !58 The local service FE The official account is small ;Picasso Open source project leader ;
Preface
Recent group sharing , need React Hooks Of useRef Related knowledge , But I found a lot of information , There is no systematic article , So I integrated some information on the Internet , Let me take you to know more about useRef.
useRef What is it?
useRef yes React 16.8 A new feature Hook Method , Of course React Hook It also contains a very rich API Method , This article is only for useRef Explain .
that useRef What is it ?
for instance :
import { useRef } from 'react';
const ref = useRef(0);
ref.current === 0 // true
Return to a variable refobject , The object has only.currentattribute , The initial value is the passed in parameter (initialValue).Back to refObjects remain the same throughout the life cycle of the component .When updated current Value does not re-render, This is theuseStateDifferent places .useRef Similar to class components this.
Popular point theory useRef It's like being able to .current Property to hold a variable value “ The box ”.
Use
notice useRef Of Ref, It must have occurred to me Class Medium createRef, Most of their usages are basically the same , All can be saved Variable perhaps Dom node , Specific differences , There is a specific introduction later in this article .
Stored variable
You can go through ref.current Property to access this ref Current variable for . This variable is intentionally set to be variable . This means that you can read and write to it .
Example 1:
import React, { useState, useRef, useCallback } from 'react'
export default function StopWatch() {
const [now, setNow] = useState(Date.now())
const ref = useRef()
const handleStart = useCallback(() => {
ref.current = setInterval(() => {
setNow(Date.now())
}, 1000)
}, [])
const handleStop = useCallback(() => {
clearInterval(ref.current)
}, [])
return (
<>
<h1>Now Time : {now}</h1>
<button onClick={handleStart}>Start</button>
<button onClick={handleStop}>Stop</button>
</>
)
}
In the above case , We use ref Storage setInterval Back to ID, When necessary , We just need clearInterval(ref.current) That's all right. .
Example 2:
import React, { useRef } from 'react';
export default function ClickWatch() {
let ref = useRef(0);
const handleClick = useCallback(() => {
ref.current = ref.current + 1;
alert('You clicked ' + ref.current + ' times!');
}, [])
return (
<button onClick={handleClick}>
Click me!
</button>
);
}
In the example above , The button will add... After each click ref.current.
ref Point to a number , however , image state equally ,ref Can point to anything : Like strings 、 Objects and even functions . And state The difference is ,ref Is an ordinary with the current property JavaScript object , Can read and modify .
Be careful : Components will not be incremented every time re-render. image state equally ,ref stay re-render Between React Retain . However ,setState will re-render Components , And set up ref Will not be .
save Dom node
⽤useRef obtain React JSX Medium DOM Elements , Once you get it, you can control DOM Anything you want .
import React, { useRef, useCallback } from 'react'
export default function TextInputWithFocusButton() {
const inputEl = useRef()
const handleFocus = useCallback(() => {
// `current` The point has been mounted to DOM Text input elements on
inputEl.current.focus()
}, [])
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={handleFocus}>Focus the input</button>
</div>
)
}
When you need to use useRef
Usually , When your component needs “ Jump out of ” React And go outside API When communication , You will use ref, It is often the case to use browsers that do not affect the appearance of components API. Here are some rare cases :
Storage timeout IDStorage and operation DOM Elements Storage does not require calculation JSX Other objects of
in addition , If your component needs to store some values , But these values will not affect render The logic of , You can choose to use ref To store .
ref Best practices
ref There are several best practices for , Following these principles will make your components more predictable :
【 hold ref As an escape pod 】: When you use an external system or browser API when ,
refIs a very useful way . If most of your application logic and data flow depend onref, You may need to reconsider whether your approach is correct , becauserefThe variability of may make your logic or data flow unpredictable .【 Not in
renderRead or write duringref.current】: If you need some data in the rendering process , Please do not useref, Instead, usestate. because React I do not know!ref.currentWhen did it change , Reading it at render time makes the behavior of components unpredictable .
React state The limitation of does not apply to ref. for example ,state It's like every time render Snapshot , And will not synchronize updates . But when you change ref When the current value of , It will change immediately :
ref.current = 5;
console.log(ref.current); // 5
This is because ref In essence, it is a common JavaScript object , So its behavior is like this .
When you use ref when , You don't need to worry about avoiding mutations . As long as the object you are mutating is not used for rendering ,React Will not care about your right ref Or what its content does .
useRef and setState Comparison of
| useRef | setState |
|---|---|
useRef(initialValue) return { current: initialValue } | useState(initialValue) return state The current value of and a status setting function ( [value, setValue]) |
It doesn't trigger when you change it re-render | It will trigger when you change it re-render |
“ Variable ”: You can rendering Modification and update outside the process current Value | “ Immutable ”: You must use the state setting function to modify the state , Line up again re-render |
You should not be in rendering Read or write in the process current Value | You can read it at any time state, However , Every time re-render It won't change by itself state snapshot |
This is a counter button implemented using state :
import React, { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
You clicked {count} times
</button>
);
}
Because it shows count Value , So use state It makes sense . When using setCount() When setting the value of the counter ,React Meeting re-render Component and update the screen to show the new count.
If you try to use ref To achieve it ,React Never re render components , So you'll never see the count change !
import React, { useRef } from 'react';
export default function Counter() {
let countRef = useRef(0);
function handleClick() {
// It's not going to be re-render This component !
countRef.current = countRef.current + 1;
}
return (
<button onClick={handleClick}>
You clicked {countRef.current} times
</button>
);
}
Click the button anyway , The page always shows You clicked 0 times
useRef and createRef The difference between
useRef Can only be used in FunctionComponent, and createRef Can only be used in ClassComponent.
review createRef Use
import React, { Component, createRef } from 'react'
export default class TextInputWithFocusButton extends Component {
constructor(args) {
super(args)
this.inputEl = createRef()
}
handleFocus = () => {
// `current` The point has been mounted to DOM Text input elements on
this.inputEl.current.focus()
}
render() {
return (
<div>
<input ref={this.inputEl} type="text" />
<button onClick={this.handleFocus}>Focus the input</button>
</div>
)
}
}
createRef stay FunctionComponent Use
Some students must be curious , If createRef Use in FunctionComponent What will happen in ?
Actually createRef Each rendering returns a new reference , and useRef The same reference is returned each time . If you don't understand , No problem . Let's use another example to deepen our understanding createRef and useRef The difference .
import React, { useRef, createRef, useState } from 'react'
export default function useRefAndCreateRef() {
const [count, setCount] = useState(1)
const refFromUseRef = useRef()
const refFromCreateRef = createRef()
if (!refFromUseRef.current) {
refFromUseRef.current = count
}
if (!refFromCreateRef.current) {
refFromCreateRef.current = count
}
const handleClick = () => {
setCount((prev) => prev + 1)
}
return (
<div>
<p>count:{count}</p>
<p>refFromUseRef{refFromUseRef.current}</p>
<p>refFromCreateRef{refFromCreateRef.current}</p>
<button onClick={handleClick}>Cause re-render</button>
</div>
)
}
Click the button to re render the component , because refFromUseRef The value of always exists ( Be similar to this ) , Cannot reassign , So it's always been 1, and createRef Each time a new reference is returned , So every update count value refFromCreateRef.current Are the latest values .
useRef Principle
Even though useState and useRef All are React Provided , But in principle useRef Can be in useState Implementation on top . You can imagine in React Inside , useRef This is how it works :
function useRef(initialValue) {
const [ref, unused] = useState({ current: initialValue });
return ref;
}
First render ,useRef Back to { current: initialValue }. This object will be React Save up , So in the next rendering , The same object will be returned , Note that there state Function settings unused In this case , Is not used . It is unnecessary , because useRef Always just return the same object !
useRef Source code
Remove redundant code from the source code , It's very simple , It is mainly divided into Mount Stage and Update Stage .
Mount Stage
At this stage , useRef And others Hook⼀ Sample creation ⼀ individual Hook object , Then create ⼀ individual {current: initialValue} Value , The cache to Hook Of memoizedState attribute , And return the value .
function mountRef<T>(initialValue: T): {|current: T|} {
const hook = mountWorkInProgressHook();
if (enableUseRefAccessWarning) {
if (__DEV__) {
//...
} else {
const ref = {current: initialValue};
hook.memoizedState = ref;
return ref;
}
} else {
const ref = {current: initialValue};
hook.memoizedState = ref;
return ref;
}
}
Update Stage
This stage is very lazy , Directly from Hook Return the previously cached value in the instance .
function updateRef<T>(initialValue: T): {|current: T|} {
const hook = updateWorkInProgressHook();
return hook.memoizedState;
}
Is this very simple ?
summary
refIt's aEscape capsule, It can be saved and not used forrenderThe data of , You don't need them often .refIt's pure.JavaScriptobject , It has a name calledcurrentProperties of , You can read or set it .You can call useRefThishookGive Way React Generate aref.similar state,refLet you in the componentsre-renderSave data between .and stateThe difference is , Set uprefOfcurrentProperty does not triggerre-render.Not in renderIn the process of reading or writingref.current, This will make your components unpredictable .
Reference resources
https://juejin.cn/post/7023983265870512135
LBG Open source project promotion :
Still writing HTML and CSS Do you ?
Still writing the layout ?
Quick use Picasso Well ,Picasso One click generation of highly available front-end code , Let you have more time to precipitate and grow , welcome Star
Open source project address :https://github.com/wuba/Picasso
Official website address :https://picassoui.58.com

边栏推荐
- FINEOS宣布2022年GroupTech Connect活动开放注册
- Mlx90640 infrared thermal imager temperature sensor module development notes (6)
- PostgreSQL在Linux和Windows安装和入门基础教程
- Marriage seeking story
- [error reporting] what do you read in the log
- Harbor2.2 用户角色权限速查
- Integrity constraints of SQL Server database
- Cohere博客:在生产环境中运行大型语言模型-推理框架概览
- 数据库组成 触发器
- 打造绿色数据中心,Colt DCS 是认真的!
猜你喜欢

Recalling Sister Feng

Meiker Studio - Huawei 14 day Hongmeng equipment development practical notes 8

An error occurred in the scrapy shell

An online duplicate of a hidden bug

Practice of microservice in solving Library Download business problems

忆凤姐

PostgreSQL在Linux和Windows安装和入门基础教程

4.1 配置Mysql与注册登录模块

CVPR 2022 单目深度估计新SOTA—NeW CRFs:Neural Window Fullyconnected CRFs

Exploration on cache design optimization of community like business
随机推荐
正点原子stm32中hal库iic模拟`#define SDA_IN() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}` //PB9 输入模式
Pyechart离线部署
系统调用捕获和分析—Ring0层kprobe劫持系统调用
Pytorch——基于mmseg/mmdet训练报错:RuntimeError: Expected to have finished reduction in the prior iteration
Data Lake (19): SQL API reads Kafka data and writes it to iceberg table in real time
Common library installation
滴滴被罚80亿!拿用户数据赚钱的时代结束了
Recalling Sister Feng
Build neural network from simple to deep
Exploration on cache design optimization of community like business
X 2 earn must rely on Ponzi startup? Where is the way out for gamefi? (top)
[error reported]exception: found duplicate column (s) in the data schema: `value`;
Redis database, which can be understood by zero foundation Xiaobai, is easy to learn and use!
Wulin headlines - station building expert competition
Swagger2.9.2 tutorial and swagger3.0.0 tutorial
3.2 创建菜单与游戏页面(下)
4.1 配置Mysql与注册登录模块
swagger2.9.2教程 与swagger3.0.0教程
Getting started step by step using g2o to solve ICP problems - estimating the transformation relationship between two sets of 3D point sets with matching relationship
Metauniverse gamefi chain game system development NFT Technology