javascript - 如何使用 onClick 从自定义 React 钩子 (API) 中获取数据并使用 TypeScript 将其显示在 Div 中?
问题描述
我是 TypeScript 甚至 React Hooks 的新手。我正在尝试从一个名为 的自定义钩子中连续获取数据,该钩子useFetch()
接受一个字符串(URL)参数:
import { useEffect, useState } from "react";
export interface Payload {
data: null | string,
loading: boolean
}
const useFetch = (url: string) => {
const [state, setState] = useState<Payload>({data: null, loading: true})
useEffect(() => {
setState(state => ({ data: state.data, loading: true }));
fetch(url)
.then(x => x.text())
.then(y => {
setState({ data: y, loading: false });
});
}, [url, setState])
return state;
}
export default useFetch;
我将该钩子导入App()
:
import React, { useState, useEffect } from "react";
import useFetch from './utils/useFetch'
import {Payload} from './utils/useFetch';
const App = () => {
const [quote, setquote] = useState<Payload>({data: null, loading: true})
const handleClick = () => setquote(data)
const data = useFetch(
"/api/rand"
);
return (
<div>
<h1>Quotes</h1>
<button onClick={handleClick}>Get Quote</button>
<div>{quote.data}</div>
</div>
)
}
export default App;
在第一次加载应用程序时,它可以工作。单击按钮时,我得到数据(报价)。
但是,当我多次单击它时,API 不会再次调用,新数据也不会通过。我相信我应该使用useEffect()
react 钩子并保持状态(也许我错了),但到目前为止我所有的尝试都无济于事。任何帮助将非常感激。如果我弄清楚了,我肯定会回答这个问题。谢谢!
解决方案
看起来你在这里混合了两个想法。
您想连续获取数据吗?(持续的意思是一直,例如,周期性地,间隔地)
或者您想在安装组件时获取数据(当前发生)并且当用户点击“获取报价”按钮(当前不工作)时?
我会尽力帮助你。
连续/定期
尝试稍微更改设置。在 useFetch 内部执行以下操作:
import { useEffect, useState } from "react";
export interface Payload {
data: null | string,
loading: boolean
}
const useFetch = (url: string) => {
const [state, setState] = useState<Payload>({data: null, loading: true})
useEffect(() => {
const interval = setInterval(() => {
setState(state => ({ data: state.data, loading: true }));
fetch(url)
.then(x => x.text())
.then(y => {
setState({ data: y, loading: false });
});
}, 2000); // Something like 2s
return () => {
clearInterval(interval); // clear the interval when component unmounts
}
}, [url])
return state;
}
export default useFetch;
这将每 2 秒获取一次端点并更新状态变量,然后这将反映在应用程序中(或任何使用该钩子的地方)。
因此,您不再需要应用程序中的报价状态。此外,您不再需要 UI 中的按钮。
应用程序看起来像:
import React, { useState, useEffect } from "react";
import useFetch from './utils/useFetch'
import {Payload} from './utils/useFetch';
const App = () => {
const quote = useFetch(
"/api/rand"
);
return (
<div>
<h1>Quotes</h1>
<div>{quote.data}</div>
</div>
)
}
export default App;
在安装组件时获取数据(当前发生)并且当用户点击“获取报价”按钮时
那么我认为 useFetch 钩子并不是真正需要/适合的。这个应用程序可以使用一个钩子,但是将它转换成一个更简单的函数对我来说更有意义。我建议省略 useFetch 钩子。App 组件看起来像:
import React, { useState, useEffect, useCallback } from "react";
const App = () => {
const [quote, setQuote] = useState<Payload>({data: null, loading: true})
const handleGetQuote = useCallback(() => {
setQuote(state => ({ data: state.data, loading: true }));
fetch("/api/rand")
.then(x => x.text())
.then(y => {
setQuote({ data: y, loading: false });
});
}, []);
useEffect(() => {
handleGetQuote();
}, [handleGetQuote]);
return (
<div>
<h1>Quotes</h1>
<button onClick={handleGetQuote}>Get Quote</button>
<div>{quote.data}</div>
</div>
)
}
export default App;
推荐阅读
- python-trio - 在没有 BrokenResourceError 的情况下终止 trio 程序的正确方法
- asp.net-mvc - 通过代码设置应用注册 (Azure AD)
- javascript - 如何检查鼠标位置是否在 HTML5 Canvas 路径内?
- spring - Spring集成`RotatingServerAdvice`轮询
- android-studio - 为什么genymotion突然停止而不显示?在安卓java中
- python - 如何获取 MText 对象的 TextString 属性?
- mongodb - $lookup 与本地数组的管道
- typescript - Google 验证码企业无法在 Prod 服务器上运行
- scripting - Inno Setup:如何仅在满足条件时显示自定义表单?
- mongodb - Mongodump 失败并显示“如果指定了多个主机,则无法建立直接连接”