将获取功能放在单独的组件中
Putting fetch function in a separate component
我正在尝试从以下组件中取出 fetchImages 函数并将其放入新组件中:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import UnsplashImage from './UnsplashImage';
const Collage = () => {
const [images, setImages] = useState([]);
const [loaded, setIsLoaded] = useState(false);
const fetchImages = (count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey =
'<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
useEffect(() => {
fetchImages();
}, []);
return (
<div className="image-grid">
{loaded
? images.map(image => (
<UnsplashImage
url={image.urls.regular}
key={image.id}
alt={image.description}
/>
))
: ''}
</div>
);
};
export default Collage;
为此,我创建了一个名为 api.js 的新组件,从上述组件中删除了整个 fetchImage 函数并像这样把它放到 api.js 中:
api.js
const fetchImages = (count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey =
'<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
export default fetchImages;
接下来我从 api.js 中取出 setIsLoaded(true); 并将其粘贴到 Collage 组件中,如下所示:
useEffect(() => {
fetchImages();
setIsLoaded(true);
}, []);
现在我可以将 fetchImages 导入到 Collage 组件中。
但是,我不知道 fetchImages 函数中的这一行应该做什么?这个需要去Collage组件,但是res.data没有在Collage组件里面定义。
setImages([...images, ...res.data]);
我该如何处理?
你可以做的是创建一个自定义挂钩(有点像 HOC)...因为我没有 unsplash API 键我会给你一个不同的例子 API 但思路是一样的:
这是您的自定义挂钩:
import { useState, useEffect } from 'react';
export const useFetch = url => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const fetchUser = async () => {
const response = await fetch(url);
const data = await response.json();
const [user] = data.results;
setData(user);
setLoading(false);
};
useEffect(() => {
fetchUser();
}, []);
return { data, loading };
};
以下是如何在您的组件中使用它:
import { useFetch } from './api';
const App = () => {
const { data, loading } = useFetch('https://api.randomuser.me/');
return (
<div className="App">
{loading ? (
<div>Loading...</div>
) : (
<>
<div className="name">
{data.name.first} {data.name.last}
</div>
<img className="cropper" src={data.picture.large} alt="avatar" />
</>
)}
</div>
);
};
这是一个现场演示:https://codesandbox.io/s/3ymnlq59xm
有很多方法可以做到这一点,但就您而言。
你应该使用
const fetchImages = (afterComplete, count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey = '<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
afterComplete(res.data);
});
};
export default fetchImages;
在您的拼贴组件中:
const afterComplete = (resData) =>{
setImages([...images, ...resData]);
setIsLoaded(true);
}
useEffect(() => {
fetchImages(afterComplete);
}, []);
我正在尝试从以下组件中取出 fetchImages 函数并将其放入新组件中:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import UnsplashImage from './UnsplashImage';
const Collage = () => {
const [images, setImages] = useState([]);
const [loaded, setIsLoaded] = useState(false);
const fetchImages = (count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey =
'<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
useEffect(() => {
fetchImages();
}, []);
return (
<div className="image-grid">
{loaded
? images.map(image => (
<UnsplashImage
url={image.urls.regular}
key={image.id}
alt={image.description}
/>
))
: ''}
</div>
);
};
export default Collage;
为此,我创建了一个名为 api.js 的新组件,从上述组件中删除了整个 fetchImage 函数并像这样把它放到 api.js 中:
api.js
const fetchImages = (count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey =
'<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
export default fetchImages;
接下来我从 api.js 中取出 setIsLoaded(true); 并将其粘贴到 Collage 组件中,如下所示:
useEffect(() => {
fetchImages();
setIsLoaded(true);
}, []);
现在我可以将 fetchImages 导入到 Collage 组件中。
但是,我不知道 fetchImages 函数中的这一行应该做什么?这个需要去Collage组件,但是res.data没有在Collage组件里面定义。
setImages([...images, ...res.data]);
我该如何处理?
你可以做的是创建一个自定义挂钩(有点像 HOC)...因为我没有 unsplash API 键我会给你一个不同的例子 API 但思路是一样的:
这是您的自定义挂钩:
import { useState, useEffect } from 'react';
export const useFetch = url => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const fetchUser = async () => {
const response = await fetch(url);
const data = await response.json();
const [user] = data.results;
setData(user);
setLoading(false);
};
useEffect(() => {
fetchUser();
}, []);
return { data, loading };
};
以下是如何在您的组件中使用它:
import { useFetch } from './api';
const App = () => {
const { data, loading } = useFetch('https://api.randomuser.me/');
return (
<div className="App">
{loading ? (
<div>Loading...</div>
) : (
<>
<div className="name">
{data.name.first} {data.name.last}
</div>
<img className="cropper" src={data.picture.large} alt="avatar" />
</>
)}
</div>
);
};
这是一个现场演示:https://codesandbox.io/s/3ymnlq59xm
有很多方法可以做到这一点,但就您而言。 你应该使用
const fetchImages = (afterComplete, count = 10) => {
const apiRoot = 'https://api.unsplash.com';
const accessKey = '<API KEY>';
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then(res => {
console.log(res);
afterComplete(res.data);
});
};
export default fetchImages;
在您的拼贴组件中:
const afterComplete = (resData) =>{
setImages([...images, ...resData]);
setIsLoaded(true);
}
useEffect(() => {
fetchImages(afterComplete);
}, []);