具有钩子损坏错误规则的反应查询

react-query with rules of hook broken error

我正在尝试使用 react-query 将我的 API 调用提取到可重复使用的挂钩中。我需要发送给这个挂钩的参数是 moduleName 和 value。出于某种原因,我得到一个错误,我需要遵循钩子规则。

请指教

这是我的代码:

export const useAutoSave = () => {
  const fetcher = useCallback(
    (
      moduleName: ISourceLoaderEditTabs,
      value: Partial<ISourceConfigurationEdit[ISourceLoaderEditTabs]>,
      saveUrl = '',
    ) => {
      const handleSaveSourceDetailsMutation = useMutation(
        (data: ISourceConfigurationEdit) =>
          saveUrl
            ? postSaveStageRaw(`${POST_SAVE_STAGE_RAW}?${saveUrl}`, data)
            : saveSourceDetails(data),
      );
      const sourceId = sessionStorage.getItem('sourceId');

      const sourceDetail = queryClient.getQueryData([
        'getSourcesDetail',
        Number(sourceId),
      ]);
      handleSaveSourceDetailsMutation.mutate(
        {
          ...(sourceDetail as ISourceConfigurationEdit),
          [moduleName]: {
            ...(sourceDetail as ISourceConfigurationEdit)[moduleName],
            ...value,
          },
        },
        {
          onSuccess: async (data) => {
            queryClient.setQueryData(
              ['getSourcesDetail', Number(sourceId)],
              data,
            );
          },
        },
      );
    },
    [],
  );

  return [fetcher];
};

然后在我的组件中我将它用作

const [fetch] = useAutoSave();

fetch('abc', {
  name:'a2441918'
})

代码片段:Stackblitz: https://stackblitz.com/edit/react-q8uvse?file=src%2Fhooks.js

错误日志中所述的问题 - useMutation

的使用
const handleSaveSourceDetailsMutation = useMutation(
        (data: ISourceConfigurationEdit) =>
          saveUrl
            ? postSaveStageRaw(`${POST_SAVE_STAGE_RAW}?${saveUrl}`, data)
            : saveSourceDetails(data),
      );

这个 useMutation 挂钩需要在 useCallback 之外。这也意味着 saveUrl 和其他参数需要重构。

export const useAutoSave = () => {
  const i_dont_know = useMutation(x,x,x,x); // hooks can't be called in regular functions 
}

挂钩规则供参考:https://reactjs.org/docs/hooks-rules.html

您不能在 useCallback 中调用 useMutation。另外,你不需要。 useMutation returns 一个对象有两个函数 - mutatemutateAsync,当你想调用你的 mutation 时你可以调用它们。所以你的自定义钩子很可能应该只 return 任何 useMutation returns。 useMutation 的第一个参数是 mutateFn - 当你调用 mutatemutateAsync 时调用的函数,你也可以在那里传递一个参数对象:

const useAutoSave = () => {
  return useMutation(
   ({ moduleName, value, saveUrl }) => saveUrl
        ? postSaveStageRaw(`${POST_SAVE_STAGE_RAW}?${saveUrl}`, data)
        : saveSourceDetails(data),
  )
}

然后您可以通过以下方式调用它:

const { mutate } = useAutoSave()

<button onClick={() => {
  mutate({ moduleName: 'something, value: 'somethingElse' })
}}>Save</button>