“React Hook “useFatherMoney“ cannot be called inside a callback. React Hooks must be called in a Rea

React Hook “useFatherMoney” cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.eslintreact-hooks/rules-of-hooks

在这里插入图片描述

报错代码

/** @format */

import React, { useState } from "react";

const Son = ({
  money,
  useFatherMoney,
}: {
  money: number;
  useFatherMoney: (money: number) => void;
}) => {
  return (
    <div>
      <p>Father的钱:{money}</p>
      <button onClick={() => useFatherMoney(money - 1)}>拿走父亲一块钱</button>
    </div>
  );
};

const Father = () => {
  const [money, setMoney] = useState<number>(100);
  return <Son money={money} useFatherMoney={setMoney}></Son>;
};

function App() {
  return <Father></Father>;
}

export default App;

解释

错误信息 “React Hook “useFatherMoney” cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.” 指出你尝试在回调函数中调用 Hook(在这种情况下是 useFatherMoney),这是不允许的。根据 React Hooks 的规则,Hooks 只能在 React 函数组件或自定义 Hooks 的顶层调用

在你的代码中,useFatherMoney 应该是一个用于修改状态的函数,你尝试将其作为 prop 传递给子组件 Son 并在 onClick 事件处理程序中调用它。但是,由于 useFatherMoney 实际上是一个更新状态的函数(在这个例子中是 setMoney),它应该封装在一个自定义 Hook 中,而不是直接作为 prop 传递。

要解决这个问题,你可以创建一个自定义 Hook 来管理状态逻辑,然后在 Father 组件中使用这个 Hook。这里是如何重构你的代码:

import React, { useState } from "react";

// 创建一个自定义 Hook 来管理父亲的钱
const useFatherMoney = (initialMoney) => {
  const [money, setMoney] = useState(initialMoney);

  const takeMoney = (amount) => {
    setMoney(money - amount);
  };

  return { money, takeMoney };
};

const Son = ({ money, takeFatherMoney }) => {
  return (
    <div>
      <p>Father的钱:{money}</p>
      <button onClick={() => takeFatherMoney(1)}>拿走父亲一块钱</button> {/* 调整金额逻辑 */}
    </div>
  );
};

const Father = () => {
  const { money, takeMoney } = useFatherMoney(100);
  return <Son money={money} takeFatherMoney={takeMoney} />;
};

function App() {
  return <Father />;
}

export default App;

在这个重构的版本中:

  • 我们创建了一个新的自定义 Hook useFatherMoney,它初始化了 money 状态并提供了 takeMoney 函数来更新状态。
  • Father 组件现在使用这个自定义 Hook 来获取 money 状态和更新状态的函数。
  • Son 组件接收 moneytakeFatherMoney 作为 props,并在按钮点击事件中调用 takeFatherMoney

这样,你就遵循了 Hooks 的规则,并且将状态逻辑封装在了自定义 Hook 中,使得状态管理更加清晰和可重用。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误提示的意思是,`useHistory` 这个 Hook 只能在函数组件和自定义 Hook 中使用,不能在类组件中使用。因为 Hooks 是 React V16.8 引入的新特性,而类组件并不支持 Hooks。 如果你想在类组件中使用路由的 `history` 对象,可以使用 `withRouter` 高阶组件。`withRouter` 接收一个组件作为参数,并返回一个新的组件。新的组件会将路由的 `history` 对象作为 `props` 传递给被包裹的组件。 具体用法如下: 1. 首先,在需要使用 `history` 对象的类组件中,导入 `withRouter` 高阶组件: ```javascript import { withRouter } from 'react-router-dom'; ``` 2. 然后,使用 `withRouter` 包裹组件: ```javascript class MyComponent extends React.Component { render() { const { history } = this.props; return ( <React.Fragment> <button onClick={() => history.push('/new-route')}> Navigate to New Route </button> </React.Fragment> ); } } export default withRouter(MyComponent); ``` 在上面的例子中,我们使用 `withRouter` 包裹了 `MyComponent` 类组件,并将包裹后的组件导出。这样,`MyComponent` 组件就可以通过 `this.props.history` 访问 `history` 对象了。 需要注意的是,`withRouter` 包裹后的组件会在路由变化时重新渲染,因此可能会造成性能问题。如果你需要在类组件中频繁地访问 `history` 对象,建议将类组件转换为函数组件,并使用 `useHistory` 钩子来获取 `history` 对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值