簡體   English   中英

在反應 function 中使用 use-State 鈎子總是拋出錯誤 + 如何與另一個組件共享變量

[英]Using use-State hook in react function always throws an error + How to share a variable with another component

我是 Javascript/Typescript 編程的初學者,即將開發我的第一個反應應用程序。 為了從后端(FastAPI)獲取一些數據,我創建了 function “GetData”,只要單擊按鈕就會執行。

組件 1:從“./socket”導入按鈕 { GetData }

export default function Button() {
    return (
        <button onClick={GetData}>
            Run
        </button>
    )
}

組件2(命名socket):websocket和數據邏輯

import {useState, createContext} from 'react';

let socket: any;

export async function ConnectWebsocket() {
    socket = new WebSocket("ws://127.0.0.1:8000/");

    socket.onopen = () => {
        console.log('connected')
    }

    socket.onclose = () => {
        console.log('closed')
    }

    socket.onerror = () => {
        console.log('error')
    }
}

export async function GetData() {
    const [data, setData] = useState({});
    
    socket.send("get Data");
    
    socket.onmessage = (event: any) => {
        const newData = JSON.parse(event.data);
        console.log(`Data from server: ${newData}`);
        setData((data) => ({ ...data, ...newData }));
    }

    console.log(`Overall data: ${data}`);
}

我面臨的問題是 useState 鈎子。 每當我通過單擊運行按鈕嘗試通過 websocket 嘗試 stream 數據時,我總是會收到以下錯誤:

未捕獲(承諾中)錯誤:無效的掛鈎調用。 鈎子只能在 function 組件的主體內部調用。 這可能由於以下原因之一而發生:

  1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能違反了 Hooks 規則
  3. 您可能在同一個應用程序中擁有多個 React 副本,請參閱https://reactjs.org/link/invalid-hook-call以獲取有關如何調試和修復此問題的提示。

我還使用 useState-hook 創建了一個小例子,這個例子很有效。 你能發現我在上面的代碼中搞砸了什么嗎?

另外我還有一個初學者問題。 您如何使“數據”變量可用於第三個組件(例如表格)?

您只能在實際反應組件中使用反應鈎子。 在您的情況下,您的 Button 組件。 所以我會做這樣的事情:

   class SocketHelper {
    socket = new WebSocket("ws://127.0.0.1:8000/");

    constructor() {
        
        socket.onopen = () => {
            console.log('connected')
        }

        socket.onclose = () => {
            console.log('closed')
        }

        socket.onerror = () => {
            console.log('error')
        }
    }
}

export const socketHelper = new SocketHelper();


export default function Button() {
    const [data, setData] = useState({});

    useEffect(() => {

        socketHelper.socket.onmessage = (event: any) => {
            const newData = JSON.parse(event.data);
            console.log(`Data from server: ${newData}`);
            setData((data) => ({ ...data, ...newData }));
        }
    }, []);

    const getData = () => {
        socketHelper.socket.emit("getdata");
    }

    return (
        <div>
            <button onClick={getData}>
                Run
            </button>
            <pre>{JSON.stringify(data, null, 2)}</pre>
        </div>
    )
}

您也在使用 socket.send 但您似乎沒有使用返回的套接字。 所以我會使用發射 function: https://socket.io/docs/v4/client-api/#socketemiteventname-args

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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