繁体   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