useEffect不能在内部直接使用异步函数
const [result,setData]=useState({hits:[]})
useEffect(async()=>{
const fetchData=async()=>{
const result=await axios('https://hn.algolia.com/api/v1/search?query=redux')
setData(result.data)
}
fetchData()
},[])
添加loading,错误码
const [result,setData]=useState({hits:[]})
const [query,setQuery]=useState('redux')
const [search,setSearch]=useState('')
const [url,setUrl]=useState('https://hn.algolia.com/api/v1/search?query=redux')
const [isLoading,setIsLoading]=useState(false)
const [isError,setIsError]=useState(false)
useEffect(()=>{
const fetchData=async()=>{
setIsLoading(true)
setIsError(false)
try{
const result=await axios(url)
setData(result.data)
}catch(error){
setIsError(true)
}
setIsLoading(false)
}
fetchData()
},[url])
// 最简单实现
return (
<>
<form onSubmit={
event=>{
setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`);
event.preventDefault();
//去掉默认行为
}
}>
<input type="text" value={query} onChange={e=>setQuery(e.target.value)}/>
输入值{query}
<button type="submit">请求</button>
</form>
<hr/>
{isError&&<div>网络好像出现了一点状况</div>}
{isLoading?(<div>Loading</div>):(
<ul>
{result.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
)}
</>
)
}
变成hook
const useHackerNewsApi = () => {
const [data, setData] = useState({ hits: [] });
const [url, setUrl] = useState(
'https://hn.algolia.com/api/v1/search?query=redux',
);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
return [{ data, isLoading, isError }, setUrl];
}
简单的ajax hook
import {useState,useEffect} from 'react'
import axios from 'axios'
export default function useHackerNewsApi(confUrl){
// 支持传入url
const [data, setData] = useState({ hits: [] });
const [url, setUrl] = useState(
'https://hn.algolia.com/api/v1/search?query=redux',
);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const [disabeled,setDisabled]=useState(false)
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
if(!disabeled){
const result = await axios(url);
setData(result.data);
}
} catch (error) {
if(!disabeled){
setIsError(true);
}
}
setIsLoading(false);
};
fetchData();
return ()=>{
disabeled=true
}
}, [url]);
return [{ data, isLoading, isError }, setUrl];
}
useRequest
1 .loading状态管理
2 .竞态处理:如果uesrId连续变化了5次,发送了5次网络请求,我们要保证总是最后依次网络请求有效。
3 .组件卸载
4 .分页处理
5 .防抖
6 .节流
7 .加载更多
8 .并行请求:同一个接口,需要维护多个请求状态
1 .删除n个不同的用户,需要维护n个请求状态
2 .多次删除同一个用户,则只需要维护最后一个请求
3 .
9 .轮询
10 .屏幕聚焦重新发起请求
11 .swr能力
1 .我们在发起网络请求的时候,会优先返回之前的缓存数据,然后再背后发起新的网络请求,最终用新的请求结果重新触发组件渲染。
网友评论