我试图访问useRef
内部封闭的函数内的React状态。然而,即使有一个辅助函数绑定到App
来访问状态,状态也不会在useRef
函数内部更新。
getCount outside 0
// after clicking, getCount inside is still 0, even though count now equals 1
getCount outside 1
getCount inside 0
import React, { useState, useRef } from 'react'
import ReactDOM from 'react-dom'
const App = function () {
const [count, setCount] = useState(0)
const getCount = function () {
return count
}.bind(App)
console.log('getCount outside', getCount())
const onClick = useRef(() => {
console.log('getCount inside', getCount())
})
return (
<>
<div onClick={() => setCount(count + 1)}>
increment count
</div>
<div onClick={onClick.current}>
{count}
</div>
</>
)
}
const wrapper = document.getElementById('root')
ReactDOM.render(<App />, wrapper)
传递给useRef
的参数仅在组件挂载时考虑。只有在那个时候才会赋值给ref;当组件重新渲染时,它不会更新。
当组件挂载时,ref函数关闭的count
变量是初始状态值,即0。无论组件重新渲染多少次,如果没有重新赋值,ref的函数仍然会在原始状态值上关闭。
如果你想让ref的函数产生一个最新的值,每次重新渲染时重新赋值。
// assign nothing notable on mount, just create a ref
const onClickRef = useRef();
// on mount and on re-render, assign a function
// with an up-to-date reference to the state variable
onClickRef.current = () => {
console.log(count);
};
虽然,在React中,通常最好是传递状态本身并使用它,而不是refs - refs通常用于使用React提供的功能更强大的工具无法完成的事情。
在setter中使用previousValue回调解决了这个问题:
const onClick = useRef(() => {
console.log(count); <----- always 0 (initial state)
setCount((previousValue)=> {
console.log(previousValue); <---- correct current value each time
return previousValue+1;
}
})
来源:这个想法来自@bogdanoff对这个问题的第一条评论。Upvoted .