- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有很多 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 始终可以获取最新数据。
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/
React 的半新内容。我有一个 useFetch Hook ,它具有所有的获取功能,我想在用户单击“加载更多项目”按钮时调用它来获取下一页的项目。 显然, { useFetch(...) }}>l
我有一个 api,它为我提供了如下方法: 按用户名搜索用户(用户名,限制) getRandomPremiumUsers(限制) getYoungUsers(maxAge, 限制) 我正在实现一个钩子(
我是 nuxt3 的新手,我不了解 useFetch 中 key 选项的作用(使用)可组合 它说; /* key: a unique key to ensure that data fetching
我有很多 React 经验,但我是 Hooks 的新手。 我有以下 useFetch Hook ,我在此 useAsync 之后修改了它钩子(Hook): import { useState, use
我已经实现了一个自定义 useFetch Hook ,因此可以在我的应用程序中进行提取: import { useEffect, useState } from 'react' const useFe
我只是不知道如何处理这里的错误: const { error, data } = useFetch('https://example.app/api/contact', { method: "P
我只是不知道如何处理这里的错误: const { error, data } = useFetch('https://example.app/api/contact', { method: "P
当我在NUXT环境中运行此代码时:。它提供了以下结果:。当我将SSR:FALSE添加到nuxt-config文件时,它已经被解析了。我对此感到困惑。
我刚开始学习 nuxtjs(对 vue.js 有一些经验),我遇到了以下问题: 我有一个简单的 todo-[id].vue 页面。它应该从 API 获取待办事项并呈现在页面上: import Sec
我刚开始学习 nuxtjs(对 vue.js 有一些经验),我遇到了以下问题: 我有一个简单的 todo-[id].vue 页面。它应该从 API 获取待办事项并呈现在页面上: import Sec
我构建了一个 useFetch 函数,该函数与此密切相关:https://www.robinwieruch.de/react-hooks-fetch-data这是它的简化版本:How to corre
我已经从 nuxt 3 官方文档中设置了 nuxt 3,并使用唯一的 useFetch() 可组合项来获取 app.vue 文件中的数据,但它返回错误 Error: fetch failed()当我们
编辑:我使用的是Nuxt 3.7.1版。我有一个Nuxt网站。我有一个服务器端点来获取内容。当页面第一次加载时,会显示当前数据。如果我刷新页面,则不会调用useFetch(基于网络日志),并显示旧数据
我是一名优秀的程序员,十分优秀!