Escape-hatches
使用ref引用值
需要组件记住某些信息,但不需要这些信息触发新的渲染 =》 ref
设置state会重新渲染组件,但是ref不会,可通过ref.current属性访问该ref的当前值
export default function Counter() {
let ref = useRef(0)
function handleClick() {
ref.current = ref.current + 1
}
}
ref组件的一个不会被React追踪的区域
可使用ref来存储【timeout ID、DOM元素和其他不影响组件渲染输出的对象】
使用ref操作DOM
React会自动更新DOM以匹配渲染输出,组件通常不需要操作DOM
有时候需要聚焦节点、滚动到此节点、,以及测量它的尺寸和位置
const inputRef = useRef(null)
<>
<input ref={inputRef}/>
</>
计算属性
并不需要Effect的情况
- 不必为了渲染而使用Effect来转换数据
- 不必使用Effect来处理用户事件
// ✔ 👌
function Form() {
const [firstName, setFirstName] = useState('泰勒')
const [lastName, setLastName] = useState('XXX')
const fullName = firstName + '' + lastName
}
// ❌
function Form() {
const [firstName, setFirstName] = useState('xxx')
const [lastName, setLastName] = useState('---')
const [fullName, setFullName] = useState('')
useEffect(() => {
setFullName(firstName + '' + lastName)
}, [firstName, lastName])
}
响应式Effect生命周期
Effect生命周期不同于组件,
组件可以:挂载、更新、卸载
Effect的功能: 开始同步某些东西,之后停止同步它
Effect依赖于时间变化的props和state,这个循环可能会发生多次
* chat.js
export function createConnection(serverUrl, roomId) {
return {
connect() {
console.log(' ======= 连接 ======== ')
},
disconnect() {
console.log(' ======= 断开连接 ======= ')
}
}
}
* App.js
function ChatRoom({roomId}) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId)
connection.connect()
return () => connection.disconnect()
}, [roomId])
}
ref和state不同之处
大多数情况下,建议使用state, ref是一种”脱围机制"
| ref | state |
|---|---|
| useRef(initialValue)返回 | useState(initialValue)返回state变量的当前值和一个state设置函数([value, setValue]) |
| 更改的时候不会触发重新渲染 | 更改时触发重新渲染 |
| 可变 - 可在渲染过程之中修改和更新current的值 | 不可变 - 必须使用state设置函数来修改state变量,从而排队重新渲染 |
| 不应在渲染期间读取(或写入)current值 | 可随时读取state,但每次渲染都有自己不变的state快照 |
ref和DOM
- ref 是一种脱围机制,用于保留不用于渲染的值。 你不会经常需要它们。
- ref是一个普通的JS对象,具有一个名为current的属性,可对其进行读取或设置
- 可通过调用useRef Hook来让React给一个ref
- 和state一样, ref允许在组件的重新渲染之间保留信息
- 和state不同,设置ref的current值不会触发重新渲染
- 不要在渲染过程中读取或写入ref.current,会导致组件无法预测
https://zh-hans.react.dev/learn/removing-effect-dependencies
学而不思则罔,思而不学则殆!

浙公网安备 33010602011771号