![](/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.