具有钩子损坏错误规则的反应查询
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
}
您不能在 useCallback
中调用 useMutation
。另外,你不需要。 useMutation
returns 一个对象有两个函数 - mutate
和 mutateAsync
,当你想调用你的 mutation 时你可以调用它们。所以你的自定义钩子很可能应该只 return 任何 useMutation
returns。 useMutation
的第一个参数是 mutateFn
- 当你调用 mutate
或 mutateAsync
时调用的函数,你也可以在那里传递一个参数对象:
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>
我正在尝试使用 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
}
您不能在 useCallback
中调用 useMutation
。另外,你不需要。 useMutation
returns 一个对象有两个函数 - mutate
和 mutateAsync
,当你想调用你的 mutation 时你可以调用它们。所以你的自定义钩子很可能应该只 return 任何 useMutation
returns。 useMutation
的第一个参数是 mutateFn
- 当你调用 mutate
或 mutateAsync
时调用的函数,你也可以在那里传递一个参数对象:
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>