簡體   English   中英

反應:未捕獲的錯誤:無效的掛鈎調用。 鈎子只能在 function 組件的內部調用

[英]React: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component

嘿,我有點新反應,想知道我做錯了什么......

我想做什么:

  1. 帶有連接按鈕的導航欄
  2. onClick 調用 CreateConnection
  3. 將結果添加到本地存儲
  4. 在不刷新的情況下將數據添加到 Navbar

現在 useEffect 無法識別 localstorage 的新增內容,因此在頁面刷新之前不會更新。

導航欄.js:

export const Navbar = () => {

    const [connectionAddress, setConnectionAddress] = useState("");

    useEffect(() => {
        if (localStorage.getItem("address")) {
            setConnectionAddress(localStorage.getItem("address"))
        }
    }, []);


    return (
         <ProfileNav
              address={connectionAddress}
         />

         <input type="submit" value="Connect" onClick={CreateConnection} /> 
    )
}

創建連接.js

const CreateConnection = async () => {

 try {

     #Connection code - when this is finished: 

     window.localStorage.setItem('address', address[0]);

  } catch (err) {
        console.error(err);
    }

}

ProfileNav.js

export const ProfileNav = ({ address }) => {
    return (
        <div>
            <li>{address}</li>
        </div>
    )
}

export default ProfileNav;

如果我只是將window.location.reload(true)添加到 CreateConnection.js 它可以工作,但我希望它在沒有刷新的情況下工作(可能使用 useState

但是,如果我嘗試像這樣將 useState 放入 CreateConnection.js 中:

 try {
     const [connectionAddress, setConnectionAddress] = useState("");

     #Connection code - when this is finished: 

     window.localStorage.setItem('address', address[0]);
     setConnectionAddress(address[0])

  } catch (err) {
        console.error(err);
    }

}

單擊按鈕時出現錯誤:未捕獲錯誤:無效掛鈎調用。 鈎子只能在 function 組件的內部調用。

正如您所發現的,React hooks 只能從 React 組件或其他 hooks 中調用。 您還應該查看更多規則https://reactjs.org/docs/hooks-rules.html

前進的一種選擇是從CreateConnection返回地址,並將其傳遞到組件中setConnectionAddress處理程序(或回調)中的onClick 另一個選項(不太推薦)是在CreateConnection中為 setState 創建一個參數並將setConnectionAddress傳遞到CreateConnection中。

創建連接.js

我們將添加返回值,並更恰當地命名它

// would recommend naming this with conventional camelCase
const createConnection = async () => {
  try {
    // Connection code - when this is finished: 
    window.localStorage.setItem('address', address[0]);
    return address[0];
  } catch (err) {
    console.error(err);
  }
}
導航欄.js

這里我們有一個處理程序updateConnectionAddress來在單擊按鈕時更新連接。 我們也可以將該代碼放在onClick的大括號內的 jsx 中,但通常最好讓 jsx 更精簡。

export const Navbar = () => {
  const [connectionAddress, setConnectionAddress] = useState("");

  useEffect(() => {
    if (localStorage.getItem("address")) {
      setConnectionAddress(localStorage.getItem("address"))
    }
  }, []);

  const updateConnectionAddress = async () = {
    const newAddress = await createConnection();
    setConnectionAddress(newAddress);
  }

  return (
    <>
      <ProfileNav address={connectionAddress} />
      <input type="submit" value="Connect" onClick={updateConnectionAddress} /> 
    </>
  )
}

本着單一責任原則的精神,我可能會考慮將本地存儲代碼也從 createConnection 移到其他地方,但我認為這超出了本主題的 scope

暫無
暫無

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

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