![](/img/trans.png)
[英]Error Message: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component
[英]React: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component
嘿,我有點新反應,想知道我做錯了什么......
我想做什么:
現在 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
中。
我們將添加返回值,並更恰當地命名它
// 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);
}
}
這里我們有一個處理程序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.