我实现了一个useFtech钩子,看起来像这样
import { useState, useEffect} from 'react'
const useFetch = (url) => {
const [ state, setState ] = useState({ isLoading: true, data: null, error: null });
useEffect(() => {
fetch(url)
.then((resp) => resp.json())
.then((result) =>
setState({
data: result.message,
isLoading: false
})
)
.catch((error) =>
setState({
error,
isLoading: false
})
);
}, []);
return state;
};
export default useFetch
允许我进行API调用,而无需重新编写此逻辑,这是我正在使用此useFetch挂钩的组件
import React from 'react';
import loader from '../loader.svg';
import useFetch from "../components/useFetch";
function DogsHoundList() {
const url = 'https://dog.ceo/api/breed/hound/images/random/15';
const {data, isLoading} = useFetch(url)
return (
<div>
{ isLoading ? <img src={loader} alt="loader" /> :data.map((dog, index) => (
<div key={dog} >
<img src={dog} alt={`${dog}-${index}`} />
</div>
))}
</div>
);
}
export default DogsHoundList
useFetch钩子返回一个isLoading值和实际数据,这意味着在我使用它的每个组件中,我总是必须检查是显示加载器还是实际组件,因此我决定使用渲染道具来处理此检查,现在有了一个看起来像这样的FetchData组件
import loader from '../loader.svg';
import useFetch from './useFetch';
export default function FetchData(props) {
const {isLoading, data} = useFetch(props.url)
return <div>{isLoading ? <img src={loader} alt="loader" /> : props.render(data)}</div>;
}
现在我可以通过这种方式进行api调用
<FetchData render={(data) => <DogList data={data}/>} url='https://dog.ceo/api/breed/hound/images/random/15' />
考虑到我将Hooks和渲染道具结合在一起的事实,我想知道这种方法是否存在问题,因为React文档指出您最终可能会结合使用这种技术,但是对于大多数情况,钩子就足够了。我很想知道这是否是结合钩子和渲染道具的好例子,还是可以更好地抽象出适用于所有API请求的“ isLoading”条件状态,而不必使用渲染道具模式