gpt4 book ai didi

reactjs - 实现 useFetch react Hook 以在提交函数中工作

转载 作者:行者123 更新时间:2023-12-04 00:55:56 26 4
gpt4 key购买 nike

我有很多 React 经验,但我是 Hooks 的新手。
我有以下 useFetch Hook ,我在此 useAsync 之后修改了它钩子(Hook):

import { useState, useEffect, useCallback } from 'react'

export default function useFetch(url, options, { immediate }) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
const [isPending, setIsPending] = useState(false)

const executeFetch = useCallback(async () => {
setIsPending(true)
setData(null)
setError(null)
await fetch(url, options)
.then((response) => response.json())
.then((response) => setData(response))
.catch((err) => setError(err))
.finally(() => setIsPending(false))
return { data, error, isPending }
}, [url, options, data, error, isPending])

useEffect(() => {
if (immediate) {
executeFetch()
}
}, [executeFetch, immediate])
return { data, error, isPending, executeFetch }
}

我的问题是我想在提交函数中使用它,而钩子(Hook)在其他函数中不起作用,就像这样(为简洁起见,代码的简化版本):

export default function SignupModal({ closeModal }) {
const { executeFetch } = useFetch(url, {options},
{ immediate: false }
)

async function handleSubmit(evt) {
evt.preventDefault()
const { data, error, isPending } = await executeFetch()
}
...
}

目前我故意在调用中抛出一个错误,但错误变量仍然是 null

我在这里错过了什么?这甚至可以用钩子(Hook)实现吗?

提前致谢!

最佳答案

React 钩子(Hook)只能在组件主体中使用,不能在另一个函数中使用。 executeFetch 本身返回 { data, error, isPending } 这使它成为一个嵌套的钩子(Hook),因此您不能在 handleSubmit 中使用它。

useFetch 已经在返回 { data, error, isPending, executeFetch } 所以 executeFetch 不需要再次返回。您可以从 useFetch Hook 访问所有这些数据。当您在组件中调用 executeFetch 数据时,数据、错误和 isPending 将由 setState 更新,这将导致您的 Hook 为这些更新的任何值返回一组新值。

export default function useFetch(url, options, { immediate }) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
const [isPending, setIsPending] = useState(false)

const executeFetch = useCallback(async () => {
setIsPending(true)
setData(null)
setError(null)
await fetch(url, options)
.then((response) => response.json())
.then((response) => setData(response))
.catch((err) => setError(err))
.finally(() => setIsPending(false))
}, [url, options, data, error, isPending])

useEffect(() => {
if (immediate) {
executeFetch()
}
}, [executeFetch, immediate])
return { data, error, isPending, executeFetch }
}

export default function SignupModal({ closeModal }) {
const { executeFetch, data, error, isPending } = useFetch(url, {options},
{ immediate: false }
)

async function handleSubmit(evt) {
evt.preventDefault()
await executeFetch()
}
...
// Example in your return function
{error != null && <Error />}
<Button state={isPending ? 'processing' : 'normal'}

}

根据评论更新

如果您需要访问您的 handleSubmit 函数中的数据或错误,您需要在您的钩子(Hook)中返回 promise 的响应/错误,这样您应该也可以访问您的 handleSubmit 中的数据/错误。

另外,我建议在用户触发 handleSubmit 之前将选项或任何其他可变数据作为参数传递给 executeFetch,以便 executeFetch 始终可以获取最新数据。

CodeSandBox Example 1

CodeSandBox Example 2

const useFetch = url => {
const [error, setError] = useState(null);
const [isPending, setIsPending] = useState(false);
const [data, setData] = useState(null);

const executeFetch = useCallback(
// Here you will access to the latest updated options.
async ({ options }) => {
setIsPending(true);
setError(null);
return await fetch(url, options)
.then(response => response.json())
.then(response => {
setData(response);
return response;
})
.catch(err => {
setError(err.message)
return err;
})
.finally(() => setIsPending(false));
},
[url, setIsPending, setError]
);
return { data, error, isPending, executeFetch }
};

const { data, executeFetch, error, isPending } = useFetch("URL");

const handleSubmit = useCallback(async (event) => {
event.preventDefault();
// I am passing hardcoded { id: 1 } as an argument. This can
// be a value from the state ~ user's input depending on your
// application's logic.
await executeFetch({ id: 1 }).then(response => {
// Here you will access to
// data or error from promise.
console.log('RESPONSE: ', response);
})
}, [executeFetch]);

另一个建议是不要在你的钩子(Hook)中传递一个 bool 值来立即触发 executeFetch,由调用者决定是否立即运行 executeFetch。

const { executeFetch, ... } = useFetch(....);
// you can call it immediately after setting the hook if you ever needed
await executeFetch()

关于reactjs - 实现 useFetch react Hook 以在提交函数中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62613709/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com