簡體   English   中英

訪問記憶函數中更新的上下文

[英]Access to updated context inside memoized function

我創建了一個需要訪問我的 AppContext 組件的組件(用於 websocket 通信,作為反應上下文)。

WebSocketContext 組件使用useCallbackuseMemo ,因此每次重新渲染 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM