我有一个按钮,该按钮的
onClick
我想使用用户已填写输入字段并存储在状态中的一些数据进行 POST
调用,然后将用户重定向到另一个页面。
我当前的代码如下所示,但出现错误:
React Hook“usePost”在函数“onAccept”中调用,该函数既不是 React 函数组件,也不是自定义 React Hook 函数
并且代码不起作用。我已经为
POST
调用创建了自己的钩子。
有什么方法可以使所需的功能发挥作用?
我追求的是能够进行 POST 调用和重定向。
简化示例:
// my function
const onAccept = () => {
const { data, loading, error } = usePost(
"MY_URL",
{ DATA: MY_DATA }
);
if (data && !error) {
navigate(`/`);
}
};
// return
<button onClick={() => onAccept()}
我可以建议您执行以下操作。
首先,您应该创建将从
usePost hook
返回的 fetch 函数。
示例。
export const usePost = () => {
const [loading, setLoading] = useState(false)
const [data, setData] = useState([])
const fetch = () => {
setLoading(loading)
apiRequest({
url: 'my_url',
method: 'GET',
}).then(response => {
setLoading(false)
setData(response.data.data)
}).catch(e => {
setLoading(false)
})
}
return {
status,
data,
fetch
}
毕竟,你可以在你的组件中调用这个钩子。它将返回
fetch
函数。你应该在内部调用 fetch onAccept
。
示例。
const { data, loading, fetch } = usePost()
const onAccept = () => {
fetch()
}
// return
<button onClick={() => onAccept()}
PS。如果您需要,您也可以从
usePost hook
返回错误。
是的,您正在调用
usePost
函数内部的 onAccept
钩子。你应该遵循 react hook 规则。
要解决您的问题,您可以这样做:
您的自定义挂钩文件:
export const usePost = () => {
const [status, setStatus] = useState()
const handlePost = useCallback(async (url, data) => {
// your api request logic in here, bellow only show example
try {
const {data, status} = await apiCall(url, data)
if (data && status === 200) navigate(`/`)
} catch (error) {
console.log(error)
}
}, [])
return { handlePost }
// to return status to component, you can use bellow.
// return { status, handlePost }
}
然后你的组件:
const YourComponent: React.FC = () => {
const { handlePost } = usePost()
// To get status: const { status, handlePost } = usePost()
// your other hooks in here
// Check status
useEffect(() => {
if (status === 200) {
// whatever you want to do
}
}, [status])
return (
<>
// Your component UI here
...
<button onClick={() => handlePost(url, data)}>
</>
)
}
您应该在组件的顶层调用自定义挂钩(例如:
usePost
),而不是像在代码中那样调用嵌套函数体(onAccept
函数体)。
首先,从 React Function 中调用 hook。阅读文档:https://reactjs.org/docs/hooks-rules.html#only-call-hooks-from-react-functions。
其次,您的
load
钩子中应该有某种 usePost
方法,例如:const { load } = usePost(...)
,以便在点击时发出 POST 请求。
所以你的处理程序将如下所示:
const onAccept = () => {
load();
// the following block move somewhere before you render the component or better use useEffect hook for that
// if (data && !error) {
// navigate(`/`);
// }
};
我希望这会有所帮助。