The first (mount) initialization of the ref, which is assigned to the currentHook.memoizedState; and then the update phase, passes the memoizedState to the new hook.
- MemoizedState is passed between the new and old hook: ReactFiberHooks.js#L615
function updateWorkInProgressHook(): Hook {
...
const newHook: Hook = {
memoizedState: currentHook.memoizedState, // 传递memoizedState
baseState: currentHook.baseState,
queue: currentHook.queue,
baseUpdate: currentHook.baseUpdate,
next: null
}
...
}
- Initialization and acquisition of ref on memoizedState ReactFiberHooks.js#L880
function mountRef<T>(initialValue: T): { current: T } {
const hook = mountWorkInProgressHook()
const ref = { current: initialValue } // 对象
hook.memoizedState = ref
return ref
}
The type of ref is {current: any}, the object type is reference passing, and the internal property current is not copied. So the value of current remains the same during the process of passing.
- Based on this, you can encapsulate a usePrevious Hook to index a constant value.
import { useRef, useEffect } from "react"
const usePrevious = value => {
const ref = useRef()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}