Reactjs 将fetch函数放在单独的组件中

Reactjs 将fetch函数放在单独的组件中,reactjs,react-hooks,Reactjs,React Hooks,我试图从以下组件中取出fetchImages函数,并将其放入新组件中: import React, { useState, useEffect } from 'react'; import axios from 'axios'; import UnsplashImage from './UnsplashImage'; const Collage = () => { const [images, setImages] = useState([]); const [loaded, s

我试图从以下组件中取出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;
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>
  );
};
const afterComplete = (resData) =>{
  setImages([...images, ...resData]);
  setIsLoaded(true);
}

useEffect(() => {
  fetchImages(afterComplete);
}, []);
现在我可以导入fetchImages到拼贴组件中

setImages([...images, ...res.data]);
但是,我不知道在fetchImages函数中该如何处理这一行?这需要转到拼贴组件,但拼贴组件中未定义res.data

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 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;
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>
  );
};
const afterComplete = (resData) =>{
  setImages([...images, ...resData]);
  setIsLoaded(true);
}

useEffect(() => {
  fetchImages(afterComplete);
}, []);
从“/api”导入{useFetch};
常量应用=()=>{
const{data,load}=useFetch('https://api.randomuser.me/');
返回(
{加载(
加载。。。
) : (
{data.name.first}{data.name.last}
)}
);
};

这里是一个现场演示:

有很多方法可以做到这一点,但在您的情况下。 你应该使用

 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;

那是一个很好的钩子,但它与你无关。