我完全是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">
×
</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;我认为我的Place值在我的按钮被点击时改变了,但是我的fetch函数没有被重新加载,我只是改变了一个值。我真的很感谢你的帮助。
发布于 2020-10-13 02:39:58
问题是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;发布于 2020-10-14 01:17:24
您可以创建一个新的useEffect,然后将该place添加到useEffect依赖项中,以创建一个副作用,以便在place变量的值发生变化时再次调用该useEffect:
// 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]);这将为您提供每次点击按钮的最新数据。
https://stackoverflow.com/questions/64322539
复制相似问题