【问题标题】:Call useEffect and re-render every time I call the same API每次调用同一个 API 时调用 useEffect 并重新渲染
【发布时间】:2022-01-16 19:14:03
【问题描述】:

在每次调用 API 时,我都会获得一个新的图片链接(https://dog.ceo/api/breeds/image/random 这是我正在调用的 API),我正在使用 useEffect 挂钩并调用 API。

每次单击按钮时,我都想点击 API,获取新值并重新渲染图像。 当我将“dog”作为依赖项传递给useEffect 时,我进入了一个无限循环,我想要的只是单击要更新图像的按钮。

  const [dog, setDog] = useState('')

  useEffect(() => {

    const getDogs = async () => {
      const dogsFromServer = await fetchDogs()
      setDog(dogsFromServer.message)
    }
    getDogs()
  }, [])

  const fetchDogs = async () => {
    const res = await fetch('https://dog.ceo/api/breeds/image/random')
    const data = await res.json()
    console.log(data.message)
    return data
  }

  const changeDog = ()=> {
    alert("changeddog")
  }

  return (
    <div className="App">
      <img src={dog}/>
      <button onClick={()=>fetchDogs()}>Change Image<button/>
    </div>
  );

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    我会将dog 状态更新也移动到fetchDogs 函数中,您可以从useEffect 和按钮的onClick 处理程序中调用。

    const [dog, setDog] = useState('');
    
    useEffect(() => {
      fetchDogs(); // <-- load dog state on initial render
    }, []);
    
    const fetchDogs = async () => {
      try {
        const res = await fetch('https://dog.ceo/api/breeds/image/random');
        const data = await res.json();
        console.log(data.message);
        setDog(data.message);
      } catch (error) {
        // log error, etc..
      }
    };
    
    const changeDog = ()=> {
      alert("changeddog")
    }
    
    return (
      <div className="App">
        <img src={dog}/>
        <button
          onClick={fetchDogs} // <-- load on button click
        >
          Change Image
        <button/>
      </div>
    );
    

    【讨论】:

    • 谢谢,成功了
    • @SyedTabeeb 太棒了!如果答案有帮助/有用,那么不要忘记someone answers 时可以做什么。干杯,祝你好运!
    【解决方案2】:

    您必须在点击事件上执行此操作,而不是获取useEffect 上的数据。 像这样的:

    function YourComponent(){
      const [dog, setDog] = useState('');
    
      const fetchDogs = async () => {
        const res = await fetch('https://dog.ceo/api/breeds/image/random');
        const data = await res.json();
        return data;
      };
    
      const handleGetDogs = async () => {
        const dogsFromServer = await fetchDogs();
        setDog(dogsFromServer.message);
      };
    
      return (
        <div className="App">
          <img src={dog}/>
          <button onClick={handleGetDogs}>Change Image<button/>
        </div>
      );
    
    }
    

    【讨论】:

      【解决方案3】:

      首先,将fetchDogs 函数移出您的组件并将getDogs 定义移出useEffect,然后从changeDog 调用getDogs 并在按钮onClick 中使用该函数:

      const fetchDogs = async () => {
          const res = await fetch('https://dog.ceo/api/breeds/image/random');
          const data = await res.json();
          console.log(data.message);
          return data;
      });
      
      function App() {
        const [dog, setDog] = useState('');
      
        const getDogs = async () => {
          const dogsFromServer = await fetchDogs();
          setDog(dogsFromServer.message);
        }
      
        useEffect(() => {
          getDogs();
        }, []);
      
        
        const changeDog = ()=> {
          // alert("changeddog");
          getDogs();
        }
      
        return (
          <div className="App">
            <img src={dog}/>
            <button onClick={changeDog}>Change Image<button/>
          </div>
        );
      }
      

      工作示例:

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        • 2020-05-09
        • 1970-01-01
        • 2020-04-23
        • 1970-01-01
        • 2019-08-14
        相关资源
        最近更新 更多