我有一个自定义钩子useWebApi
,该钩子可以调用网络api并返回api结果。
function useWebApi(method, url) {
const [fetching, setFetching] = useState(true);
const [result, setResult] = useState(null);
useEffect(() => {
axios[method](url).then(res => {
setFetching(false);
setResult(res);
})
}, [url]);
return [fetching, result];
}
,我想做的事情是,获取url1
,如果获取了url1
,则获取url2
。这两个API是非独立的,url2
仅在url1
完成提取后才能调用。
所以我写下面的代码
const url1 = '/login';
const url2 = '/getMyUserInfo';
function App() {
const [fetching1, result1] = useWebApi('get', url1);
if (result1) {
const [fetching2, result2] = useWebApi('get', url2);
}
return (
<div>
{result1}
{result2}
</div>
)
}
但是在if
语句中不能调用hook,所以我将其更改为
const url1 = '/login';
const url2 = '/getMyUserInfo';
function App() {
const [fetching1, result1] = useWebApi('get', url1);
useEffect(() => {
if (result1) {
const [fetching2, result2] = useWebApi('get', url2);
}
}, [result1])
return (
<div>
{result1}
{result2}
</div>
)
}
但是,仍然存在问题,我无法渲染result2
,因为它位于嵌套作用域内,那么如何解决呢?
答案 0 :(得分:3)
您可以做的是公开一个doFetch
方法,等等,该方法将允许手动调用该挂钩。
function useWebApi(method, url) {
const [fetching, setFetching] = useState(true);
const [result, setResult] = useState(null);
const doFetch = useCallback((fetchUrl = url) => {
axios[method](fetchUrl).then(res => {
setFetching(false);
setResult(res);
})
}, [method, url])
useEffect(() => {
if (url) {
doFetch();
}
}, [doFetch]);
return [fetching, result, doFetch];
}
function App() {
const [fetching1, result1, doFetch1] = useWebApi('get', url1);
const [fetching2, result2, doFetch2] = useWebApi('get');
useEffect(() => {
if (result1) {
doFetch2(url2);
}
}, [result1])
return (
<div>
{result1}
{result2}
</div>
)
}
答案 1 :(得分:0)
如果第二个调用不依赖于第一个调用的结果值(即它们是两个独立的GET请求),则继续进行操作,并按照钩子的预期在顶层调用它们,并仅在结果为一个时才有选择地呈现结果二存在。
function App() {
const [fetching1, result1] = useWebApi('get', url1);
const [fetching2, result2] = useWebApi('get', url2);
return (
<div>
{result1}
{result1 ? result2 : null}
</div>
)
}
答案 2 :(得分:0)
您也许可以将条件移到钩子中
function useWebApi(method, url, flag = true) {
const [fetching, setFetching] = useState(true);
const [result, setResult] = useState(null);
useEffect(() => {
if(flag) {
axios[method](url).then(res => {
setFetching(false);
setResult(res);
})
}
}, [url, flag]);
return [fetching, result];
}
function App() {
const [fetching1, result1] = useWebApi('get', url1);
const [fetching2, result2] = useWebApi('get', url2, !!result1);
return (
<div>
{result1}
{result2}
</div>
)
}