[英]React: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component
Hey i'm slightly new to react and wondering what i'm doing wrong...嘿,我有点新反应,想知道我做错了什么......
What i'm trying to do:我想做什么:
Right now the useEffect doesn't recognize the new addition to localstorage so won't update until page refresh.现在 useEffect 无法识别 localstorage 的新增内容,因此在页面刷新之前不会更新。
Navbar.js:导航栏.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} />
)
}
CreateConnection.js创建连接.js
const CreateConnection = async () => {
try {
#Connection code - when this is finished:
window.localStorage.setItem('address', address[0]);
} catch (err) {
console.error(err);
}
}
ProfileNav.js ProfileNav.js
export const ProfileNav = ({ address }) => {
return (
<div>
<li>{address}</li>
</div>
)
}
export default ProfileNav;
If i simply add window.location.reload(true)
to CreateConnection.js it works but i want it to work without a refresh (possibly with useState如果我只是将
window.location.reload(true)
添加到 CreateConnection.js 它可以工作,但我希望它在没有刷新的情况下工作(可能使用 useState
But if i try to put the useState in CreateConnection.js like so:但是,如果我尝试像这样将 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);
}
}
i get the error when i click on the button: Uncaught Error: Invalid hook call.单击按钮时出现错误:未捕获错误:无效挂钩调用。 Hooks can only be called inside of the body of a function component.
钩子只能在 function 组件的内部调用。
As you've discovered, react hooks are only supposed to be called from React components or from other hooks.正如您所发现的,React hooks 只能从 React 组件或其他 hooks 中调用。 There's a few more rules that you should look into as well https://reactjs.org/docs/hooks-rules.html .
您还应该查看更多规则https://reactjs.org/docs/hooks-rules.html 。
One option moving forward is to return the address from CreateConnection
, and pass that into setConnectionAddress
in the onClick
handler (or a callback) in your component.前进的一种选择是从
CreateConnection
返回地址,并将其传递到组件中setConnectionAddress
处理程序(或回调)中的onClick
。 Another option (less recommended) would be to create a parameter for setState in CreateConnection
and pass setConnectionAddress
into CreateConnection
.另一个选项(不太推荐)是在
CreateConnection
中为 setState 创建一个参数并将setConnectionAddress
传递到CreateConnection
中。
We'll add the return, and also name this a bit more appropriately我们将添加返回值,并更恰当地命名它
// 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);
}
}
Here we a handler updateConnectionAddress
to update the connection when the button is clicked.这里我们有一个处理程序
updateConnectionAddress
来在单击按钮时更新连接。 We could also put that code in the jsx within onClick
's curly braces, but it's usually better to keep the jsx leaner.我们也可以将该代码放在
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} />
</>
)
}
In the spirit of the single responsibility principle, I would likely consider moving the local storage code elsewhere from createConnection as well, but I think that's out of scope for this topic本着单一责任原则的精神,我可能会考虑将本地存储代码也从 createConnection 移到其他地方,但我认为这超出了本主题的 scope
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.