【问题标题】:React hooks - Can't use hook inside plain async function?反应钩子 - 不能在普通异步函数中使用钩子?
【发布时间】:2022-02-17 02:51:37
【问题描述】:

我是 hooks 的新手,到目前为止印象深刻,但是,如果我尝试在函数内部使用 hooks,它似乎会抱怨(无效的​​ hook 调用。只能在函数组件的主体内部调用 hooks . 这可能是由于以下原因之一)。

我在一个基本文件中有几个常用的 API 函数,用于从 API 中检索数据。他们不返回任何东西,只是将(useDispatch)分发到商店,并且使用此状态的相关组件在整个应用程序中更新。我知道这可能是原因,因为它没有返回 React 元素,但有没有办法解决这个问题或更好、更“推荐”的 React 方法?如果我必须手动传入用户并在父组件中分派返回的结果,这不是世界末日,但我宁愿将它保存在一个地方并在这个函数中处理它,以便所有父组件都有要做的就是在状态改变时更新。

这是函数:

export async function getCar(id) {

  // It's complaining about these hooks
  const { user } = useSelector(state => state.auth);
  const dispatch = useDispatch();

  try {
      let response = await axios.get(`${baseURL}api/cars/getCar/${id}/${user.id});
      if (response.data.successCode === 200) dispatch(setCar(response.data));
  } catch (error) {

  }
}

用法:const carsList = getCar("id");

谢谢大家, 非常感谢。

【问题讨论】:

  • 你需要在功能组件的主体块中拥有所有的钩子。不能用在其他功能里面。
  • 这在 react 文档中的 hooks 规则中有解释:reactjs.org/docs/hooks-rules.html

标签: javascript reactjs function react-hooks


【解决方案1】:

钩子不同于函数。考虑到要实现自定义钩子,首先需要在钩子名称前加上 use

其次,钩子不能返回异步值,除非您将其存储在状态中。您还需要使用 useEffect 函数来确保 api 请求仅被触发一次或在 id 参数更改时触发。

export function useGetCar(id) {
  // It's complaining about these hooks
  const { user } = useSelector(state => state.auth);
  const dispatch = useDispatch();
  useEffect(() => {
     async function myFn() {
        try {
              let response = await axios.get(`${baseURL}api/cars/getCar/${id}/${user.id});
              if (response.data.successCode === 200) dispatch(setCar(response.data));
        } catch (error) {

        }

      }
      fn()
  }, [id])
}

此外,由于您只是在更新状态,您可以编写另一个选择器来从 redux 存储中获取汽车值

用法:

const Comp = ({id}) => {
    useGetCar(id);
    const car = useSelector(state => state.car);
}

【讨论】:

  • 缺少效果依赖项:dispatchuser.id。您可以添加dispatch,因为它来自 react-redux 并且不会改变但会使 linter 安静下来。然而; user.id 很重要,因为您可能希望在更改时再次实际运行效果。
  • @HMR,是的,有道理,您可以将 user.id 和 id 作为依赖项添加到 useEffect
  • 谢谢你。它真的为我清除了钩子的用例!还有一件事;调用钩子后如何传入参数? (所以做了一个更新)。我知道这将是 useGetCar(id),但是如果我想先使用 useGetCar() 来获取所有汽车,然后在搜索时传入一个 id 怎么办?你不能做 onChange={value => useGetCar(value)} 因为它会破坏被调用的钩子的顺序?谢谢
  • @user.io 在这种情况下,您有几个选择,要么实现 useGetCar ,如果传递的 id 为空,则获取所有汽车,当您想通过 id 获取所有汽车时,您更新状态中的 id 被传递给钩子并为您获取数据。另一种解决方案是从钩子中公开一个函数,您可以调用该函数以通过 Id 获取汽车
  • 谢谢@ShubhamKhatri!!这真的把一切都弄清楚了。我会将一个状态传递给钩子,该钩子将触发效果更新并通过 id 获取。现在这完全有道理。非常感谢您的帮助 - 谢谢 :)
【解决方案2】:

Hooks 是让你从函数组件中“挂钩”到 React 状态和生命周期特性的函数。 Hooks 在类中不起作用——它们让你可以在没有类的情况下使用 React。

您不能在if 语句、函数、循环和they can't be nested in anything 中放置钩子。

只能在函数组件主体的顶层内部调用钩子。

阅读official documentation

【讨论】:

    猜你喜欢
    • 2020-09-27
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多