React 自定义 Hook - useFetch
如果你想看的话,我有一个 YouTube 视频😎🍿。
为什么要使用Fetch?
当用户访问某个页面时获取数据是很常见的。我们在获取这些数据时也使用通用的逻辑。
我们的组件中还包含大量的样板/逻辑,而且不太符合 DRY(不要重复自己)。
这些都是创建自定义钩子的理由。我们可以将这些样板/逻辑外包到一个单独的文件中。该文件将保存函数(钩子),该函数将返回我们在组件中需要使用的内容。
旧方法
在这个例子中,我将使用useState
钩子来跟踪加载状态、任何错误以及数据。我将使用useEffect
钩子来运行所有这些代码。最后,我使用 axios 来获取数据,并使用取消令牌来取消任何我们不再需要的未完成请求。
//App.js
import { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
function App() {
const [quote, setQuote] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
setLoading('loading...')
setQuote(null);
setError(null);
const source = axios.CancelToken.source();
axios.get('https://api.quotable.io/random', { cancelToken: source.token })
.then(res => {
setLoading(false);
setQuote(res.data.content);
})
.catch(err => {
setLoading(false)
setError('An error occurred. Awkward..')
})
return () => {
source.cancel();
}
}, [])
return (
<div className="App">
<button onClick={fetchQuote}>Fetch Quote</button>
{ loading && <p>{loading}</p> }
{ quote && <p>"{quote}"</p> }
{ error && <p>{error}</p> }
</div>
)
}
export default App;
代码太多了。我们把大部分代码移走。
新方法
我们将创建另一个名为 的文件useFetch.js
。您需要以“use”开头自定义钩子的名称,以便 React 知道将其视为钩子。
让我们复制 import 语句、所有 3 个 useStates 和 useEffect 函数。
//useFetch.js
import { useState, useEffect } from 'react';
import axios from 'axios';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
setLoading('loading...')
setData(null);
setError(null);
const source = axios.CancelToken.source();
axios.get(url, { cancelToken: source.token })
.then(res => {
setLoading(false);
//checking for multiple responses for more flexibility
//with the url we send in.
res.data.content && setData(res.data.content);
res.content && setData(res.content);
})
.catch(err => {
setLoading(false)
setError('An error occurred. Awkward..')
})
return () => {
source.cancel();
}
}, [url])
return { data, loading, error }
export default useFetch;
你可能注意到了一些变化。首先,这个函数(也就是我们的钩子)名为 useFetch。它接收一个参数,该参数是我们想要从中获取数据的 URL。
我们还将其改为setQuote
,setData
使其更加灵活。请注意,我们还会检查多个响应,以使其更加灵活。
最后,我们的 useFetch 函数(钩子)返回我们的数据、加载和任何错误。
我把它们放在一个对象中,这样我们就可以在组件中访问它们时使用对象解构。这样,解构它们的顺序就无关紧要了,而且我们可以根据需要重命名它们。接下来我会演示这一点。
在我们的组件中使用 useFetch
回到我们的 App 组件,我们将从 导入 useFetch 钩子useFetch.js
,并传入我们想要获取数据的 URL。我们将使用对象解构来访问所需的数据。最后,我们将 data 重命名为 quote。
import useFetch from './useFetch';
import './App.css';
function App() {
const { data: quote, loading, error } = useFetch('https://api.quotable.io/random')
return (
<div className="App">
{ loading && <p>{loading}</p> }
{ quote && <p>"{quote}"</p> }
{ error && <p>{error}</p> }
</div>
);
}
export default App;
非常干净😎。
结论
自定义 hooks 对于简化代码非常有用。你可以在自定义 hooks 中使用 React hooks(毕竟它们都是函数!👍)。你可以封装大量重复的逻辑,然后从自定义 hooks 中返回所需的内容。
如果您喜欢了解类似的主题,请随时查看我的YouTube或Instagram。
希望这对某人有帮助,感谢您的阅读!
-安德鲁
文章来源:https://dev.to/techcheck/custom-react-hook-usefetch-eid