繁体   English   中英

反应钩子 - 不能在普通异步 function 中使用钩子?

[英]React hooks - Can't use hook inside plain async function?

我是钩子的新手,到目前为止印象深刻,但是,如果我尝试在 function 中使用钩子,它似乎会抱怨(无效的钩子调用。只能在 function 组件的主体内部调用钩子。这可能发生以下原因之一)。

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

这是 function:

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");

谢谢大家,非常感谢。

挂钩与 function 不同。 考虑到你想实现一个自定义钩子,你首先需要在你的钩子名称前加上use

其次,钩子不能返回异步值,除非您将其存储在 state 中。 您还需要使用 useEffect function 以确保 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])
}

此外,由于您只是更新 state 您可以编写另一个选择器以从 redux 商店获取汽车值

用法:

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

钩子是让你“钩入”React state 和 function 组件的生命周期特性的函数。 Hooks 在类中不起作用——它们让你在没有类的情况下使用 React。

你不能在if语句、函数、循环中放置钩子, 它们也不能嵌套在任何东西中

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

阅读官方文档

我设法通过使用useCallback和 window 事件从普通的 javascript 触发渲染。

// in the hooks file
export const useForceUpdate = () => {
  const [, setTriggerUpdate] = useState(0);
  const update = useCallback(() => {
    setTriggerUpdate((tick) => tick + 1);
  }, []);
  return update;
};
const handleMyOutsideCall= (
  callback: () => void
) => {
  window.addEventListener("myEvent", (e: CustomEvent) => {
    const data = e.detail;
    callback(data);
  });
};


export const dispatchMyOutsideCall = (name: string) => {
  const event = new CustomEvent("myEvent", {
    detail: {
      name: name,
    },
  });
  window.dispatchEvent(event);
};

// import useForceUpdate from hooks file 
export function MyComponent() {
  const {data, setData} = React.useContext(SomeContext);

  const update = useForceUpdate();
  useEffect(() => {
    handleMyOutsideCall(update);
  }, []);

  return <>App</>
}

然后在外部的一些其他es模块中反应scope:

   // this will trigger state update on MyComponent
   dispatchMyOutsideCall("My_Test")

希望能帮助到你

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM