![](/img/trans.png)
[英]Function passed as context value can't access updated component state when called by a consumer
[英]Access to updated context inside memoized function
我創建了一個需要訪問我的 AppContext 組件的組件(用於 websocket 通信,作為反應上下文)。
WebSocketContext 組件使用useCallback和useMemo ,因此每次重新渲染 AppContext 時都不會重新創建 websocket 連接。
我無法弄清楚為什么在.onmessage執行時我無法訪問 appContext 的當前值。 基本上,我得到的是appContext的初始值。
我該怎么做才能獲得當前值?
應用程序.js
<AppContext>
<WebSocketProvider>
...
WebSocketContext.js
import React, { useEffect, useContext, useCallback, useMemo, useState } from 'react';
import { w3cwebsocket as W3CWebSocket } from "websocket";
import { AppContext } from "./AppContext.js";
export const WebSocketContext = React.createContext(null);
const WebSocketProvider = ({ children }) => {
const [appContext, setAppContext] = useContext(AppContext);
const [wsClient, setWsClient] = useState(null);
const sendMessage = useCallback((message) => {
wsClient.send(message);
});
const connect = useCallback(() => {
console.log(Date.now(), appContext.activeZone); //access to current value of appContext is OK
let tmpWsClient = new W3CWebSocket("wss://127.0.0.1:5000");
tmpWsClient.onmessage = (message) => {
const msgObj = JSON.parse(message.data);
console.log("[Message received!]", Date.now(), appContext.activeZone); //not the current value of appContext! (actually, the initial value)
};
tmpWsClient.onopen = (event) => { ... };
tmpWsClient.onclose = (event) => { ... };
tmpWsClient.onerror = (err) => { ... };
return tmpWsClient;
});
//at 1st render of the component, create websocket client
useEffect(() => {
if (!wsClient) {
const tmpWsClient = connect();
//set websocket context
setWsClient(tmpWsClient);
}
}, []);
//this triggers as expected
useEffect(() => {
console.log("activeZone change detected:", appContext.activeZone);//access to current value of appContext is OK
}, [appContext.activeZone]);
const contextValue = useMemo(
() => ({
client: wsClient,
sendMessage
}), [wsClient, sendMessage]);
return (
<WebSocketContext.Provider value={contextValue}>
{children}
</WebSocketContext.Provider>
);
};
const context = ({children}) => WebSocketProvider({children});
export default context;
您在connect
中要做的就是在您的 useCallBack 中設置在需要時更新記憶函數所需的數據
const connect = useCallback(() => {
console.log(Date.now(), appContext.activeZone);
let tmpWsClient = new W3CWebSocket("wss://127.0.0.1:5000");
tmpWsClient.onmessage = (message) => {
const msgObj = JSON.parse(message.data);
console.log("[Message received!]", Date.now(), appContext.activeZone);
(actually, the initial value)
};
tmpWsClient.onopen = (event) => { ... };
tmpWsClient.onclose = (event) => { ... };
tmpWsClient.onerror = (err) => { ... };
return tmpWsClient;
},[appContext]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.