React hooks:在监听器中获取 useState 的状态
React hooks: get state of useState inside a listener
我的组件中有这个:
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
console.log('Here not up to date :(', pendingMessages);
setPendingMessages([ ...pendingMessages, newMessage ]);
}
问题是 pendingMessages
在侦听器中不是最新的,因为它不在渲染器中。它已经附上了。我该如何解决这个问题?
谢谢!
问题是因为效果为 运行 时形成的关闭。由于您仅在初始安装时将 useEffect
设置为 运行,因此它从声明时形成的闭包中获取 pendingMessages
的值,因此即使 pendingMessages
更新后,onSendMessage
中的 pendingMessages
将引用最初存在的相同值。
由于您不想访问 onSendMessage
中的值而只是根据先前的值更新状态,因此您可以简单地使用 setter
的回调模式
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
setPendingMessages(prevState =>([ ...prevState, newMessage ]));
}
我的组件中有这个:
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
console.log('Here not up to date :(', pendingMessages);
setPendingMessages([ ...pendingMessages, newMessage ]);
}
问题是 pendingMessages
在侦听器中不是最新的,因为它不在渲染器中。它已经附上了。我该如何解决这个问题?
谢谢!
问题是因为效果为 运行 时形成的关闭。由于您仅在初始安装时将 useEffect
设置为 运行,因此它从声明时形成的闭包中获取 pendingMessages
的值,因此即使 pendingMessages
更新后,onSendMessage
中的 pendingMessages
将引用最初存在的相同值。
由于您不想访问 onSendMessage
中的值而只是根据先前的值更新状态,因此您可以简单地使用 setter
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
setPendingMessages(prevState =>([ ...prevState, newMessage ]));
}