React 功能组件访问状态 in useEffect
Posted
技术标签:
【中文标题】React 功能组件访问状态 in useEffect【英文标题】:React functional component access state in useeffect 【发布时间】:2021-04-15 15:00:34 【问题描述】:我有一些如下所示的反应组件。作为回报,我可以使用“消息”,但如果我尝试访问某个函数或 useEffect 中的消息,例如,我总是会成为初始值。如何在功能组件中解决它?谢谢
const Messages = () =>
const websocket = useContext(WebsocketsContext);
let [ messages, setMessages ] = useState([]);
useEffect(() =>
getMessages()
.then(result =>
setMessages(result);
)
, []);
useEffect(() =>
if(websocket != null)
websocket.onmessage = (msg) =>
let wsData = JSON.parse(msg.data);
if(wsData.message_type == 'Refresh')
console.log(messages)
;
;
;
, [websocket]);
return(
<div>...</div>
);
;
export default Messages;
【问题讨论】:
【参考方案1】:您好像遇到过stale closure
在其依赖数组中带有 [websockets]
的 useEffect 只会在 websocket 引用/值更改时“更新”。无论何时,该函数都会在那个时间点围绕messages
创建一个“闭包”。因此,消息的值将保持在该闭包中。如果消息在 websocket 创建后更新,它永远不会更新 onmessage 回调函数中“消息”的值。
要解决此问题,请将“消息”添加到依赖项数组。 [websockets, messages]
。这将确保 useEffect 回调始终具有最新的消息状态,并且 onmessage 函数将具有最新的消息状态。
useEffect(() =>
if(websocket != null)
websocket.onmessage = (msg) =>
let wsData = JSON.parse(msg.data);
if(wsData.message_type == 'Refresh')
console.log(messages)
;
;
;
, [websocket, messages]);
【讨论】:
谢谢,这很容易)【参考方案2】:这是因为您的 getMessages()
是一个异步函数。顺序如下:最初安装组件并初始化值 -> 调用 componentDidMount() 意味着调用您的 getMessages()
(异步函数!)-> 初始化您的 webaocket
并调用第二个 useEffect
,它读取messages
的初始值 -> 你的getMessages
得到它的响应并相应地设置messages
。
要使其按预期工作,请将第二个 useEffect
的依赖数组设置为 [websocket, messages]
。
【讨论】:
以上是关于React 功能组件访问状态 in useEffect的主要内容,如果未能解决你的问题,请参考以下文章
测量你的组件在 React Native 功能组件中渲染的次数
React:如何使用功能性 usestate/useEffect 复制特定的组件类 setstate 回调示例?