修改输入框后,send,function 组件捕获渲染的值总是上一次send的值,如何解决这个问题
export default function ProfilePage() {
const [message, setMessage] = useState('');
const showMessage = () => {
console.log('message: ' + message); //获取的永远是上一次send之前的值 点击前输入框的值
};
const handleSendClick = () => {
setTimeout(showMessage, 1000);
};
const handleMessageChange = (e) => {
setMessage(e.target.value);
};
return (
<>
<input value={message} onChange={handleMessageChange} />
<button onClick={handleSendClick}>Send</button>
</>
);
}
解决方案
export default function ProfilePage() {
const [ message, setMessage ] = useState( '' );
// Keep track of the latest value.
const latestMessage = useRef( '' );
useEffect( () => {
latestMessage.current = message;
} );
const showMessage = () => {
console.log( 'message: ' + message ); //获取的永远是上一次send之前的值 点击前输入框的值
console.log( 'You input latest value: ' + latestMessage.current ); //最新值
};
const handleSendClick = () => {
setTimeout( showMessage, 1000 );
};
const handleMessageChange = ( e ) => {
setMessage( e.target.value );
};
return (
<>
<input value={ message } onChange={ handleMessageChange }/>
<button onClick={ handleSendClick }>Send</button>
</>
);
}
本质上,useRef 就像是可以在其 .current 属性中保存一个可变值的“盒子”。
你应该熟悉 ref 这一种访问 DOM 的主要方式。如果你将 ref 对象以
<div ref={myRef} />
形式传入组件,则无论该节点如何改变,React 都会将 ref 对象的.current
属性设置为相应的 DOM 节点。
然而,
useRef()
比ref
属性更有用。它可以很方便地保存任何可变值,其类似于在class
中使用实例字段的方式。
这是因为它创建的是一个普通
Javascript
对象。而 useRef() 和自建一个{current: ...}
对象的唯一区别是,useRef
会在每次渲染时返回同一个 ref 对象。
请记住,当
ref
对象内容发生变化时,useRef
并不会通知你。变更.current
属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调ref
来实现。
https://zh-hans.reactjs.org/docs/hooks-reference.html#useref