【问题标题】:refetch data from API using react hooks使用反应钩子从 API 重新获取数据
【发布时间】:2021-01-27 01:02:37
【问题描述】:

我是一个完整的 react 初学者,我编写了一个 fetch 组件,它使用 usefetch 函数从 API 返回数据。在我的应用程序中,我可以手动更改输入以从 API 获取不同的数据,但我想要的是有一个输入字段和一个按钮,当它被单击时,它会从 API 返回新数据。使用下面的代码,我只能在组件挂载时获取数据一次,如果我提供输入,则没有任何反应。

import React , {useState ,useEffect} from 'react';
import useFetch from './fetch'; //fetch api  code imported 
import SearchIcon from '@material-ui/icons/Search';
import InputBase from '@material-ui/core/InputBase';
import Button from '@material-ui/core/Button';

  function City(){
    
    
    const searchStyle = {
      display:"flex",
      justifyContent:"flex-start",
      position:"absolute",
      top:"400px",
      left:"40%",
    } 

        

    
    const [inputVal , setInputVal]  = useState(''); //store input value 
    const [place,setPlace] = useState('london');  //get london data from api by manually changing value new data is succesfully dislayed 
    const {loading , pics}  = useFetch(place); //fetch data 
    const [images , setImages] = useState([]); //store fetched imgs 

    const removeImage = (id) =>{
      setImages((oldState)=>oldState.filter((item)=> item.id !== id))
    }


    useEffect(()=>{
      setImages(pics);
    } , [pics] ) 
    
    //load and display fetched images 
    return (<div className="city-info">
       
      {
        !loading ? 
        
          (images.length>0 && images.map((pic) =>{
            return  <div className="info" key = {pic.id}>
                     <span className="close" onClick= {()=>removeImage(pic.id)} >
                        <span
                          className="inner-x">
                          &times;
                        </span>
                      </span>
                      <img src = {pic.src.original} alt ="img"/> 
                      <div style = {{position:"absolute" ,margin:"10px"}}> 
                        <strong>From : </strong> 
                         {pic.photographer}  
                      </div>
                    </div>
          })
        
        ):<div> Loading   </div>

      }

        <div  style = {searchStyle} >
            <SearchIcon />
             //when input changes store it 
            <InputBase onChange={(e)=>setInputVal(e.target.value)}   placeholder="Enter input" style= {{backgroundColor:"lightgrey"}}/>
            //new fetch data based on input by clicking on button nothing happens onclick 
            <Button onClick= {()=>setPlace(inputVal)} color="primary" variant = "contained" > Find </Button>
        </div>  

    </div>);
  }

export default City;

fetch.js 我的代码连接到 api :

import { useState, useEffect } from 'react';

function useFetch(url){

  
  const [loading ,setLoading] = useState(false);
  const [query,setQuery] = useState(url);
  const [pics,setPics]  = useState([]);
  
  const getPics = async()=>{
    setLoading(true);
      const response = await fetch(
        `https://api.pexels.com/v1/search?query=${query}&per_page=4`,
        {
          method:"GET",
          headers:{
            Accept:"application/json",
            Authorization:key
          }
        }
      );
    const result = await response.json();
    setPics(result.photos ?? []);
    setLoading(false);
  }
  
  
  useEffect(()=>{
    getPics();
  },[query]);


  return {loading , pics ,query  ,setQuery , getPics};

}

export default useFetch;

我认为当我的按钮被点击时我的位置值发生了变化,但我的 fetch 函数没有重新加载,我只是改变了一个值。 非常感谢您的帮助。

【问题讨论】:

  • 您能否展示在您的 API 和组件之间建立连接的代码,是否正在使用基于 Promise 的 HTTP 客户端进行请求,如果是,那么信息将很好地解决您的问题跨度>
  • @nedam Kailash 是一分钟
  • 我已经使用 axios 进行了一些 API 调用,如果需要,您可以在 github 帐户中查看它

标签: reactjs react-hooks fetch


【解决方案1】:

您可以创建一个新的 useEffect,然后将 place 添加到 useEffect 依赖项中,以创建一个副作用,以便在 place 变量的值更改后再次调用 API:

  // return the read function as well so you can re-fech the data whenever you need it
  const {loading , pics, readData}  = useFetch(place);
  
  useEffect(() => {
    readData(place);
    setImages(pics)
  }, [place]);

这将为您提供每次按钮点击的最新数据。

【讨论】:

    【解决方案2】:

    问题是useFetch 正在存储传递给useState 的初始url:

    const [query,setQuery] = useState(url);
    

    place 更新时,useFetch 永远不会使用它,并且永远不会重新触发效果。我认为,如果您完全从 useFetch 中删除此状态,它应该可以按您的预期工作:

    import { useState, useEffect } from 'react';
    
    function useFetch(url) {
      const [loading, setLoading] = useState(false);
      const [pics, setPics]  = useState([]);
      
      const getPics = async () => {
        setLoading(true);
        const response = await fetch(
          `https://api.pexels.com/v1/search?query=${query}&per_page=4`,
          {
            method: "GET",
            headers: {
              Accept: "application/json",
              Authorization: key
            }
          }
        );
        const result = await response.json();
        setPics(result.photos ?? []);
        setLoading(false);
      }
      
      
      useEffect(()=>{
        getPics();
      }, [url]);
    
    
      return { loading, pics, getPics };
    
    }
    
    export default useFetch;
    
    

    【讨论】:

    • 非常感谢您的帮助。我花了大约 2 个小时才完成这个
    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 2020-04-23
    • 2020-02-03
    • 2019-08-03
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多