React 简单 useEffect 无限循环

发布于 2025-01-09 09:38:43 字数 1084 浏览 0 评论 0原文

我不明白为什么这段代码是无限循环。这是因为我在 else if 条件下更新了我的状态。但我想在获得新的 api 答案时更新一组 url。

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  const [items, setItems] = useState({});

  useEffect(() => {
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )
  }, [])

  if (error) {
    return <div>Error : {error.message}</div>;
  } else if (!items.result) {
    return <div>Loading...</div>;
    console.log("no item");
  } else {
    setUrls([urls, items]);
    console.log("items", items);
    console.log("urls", urls);
    return <ul> {items.result.short_link}</ul>;
  }
}


export default getShortenUrl;

实际上,当谈到状态时,我有点迷失了。我不明白如何创建 url 数组并能够在其他组件中使用它。

I do not understand why this code is an infinit loop. I this it is because I update my state in else if condition. But i'd like to update an array of urls when getting new api answer.

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  const [items, setItems] = useState({});

  useEffect(() => {
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )
  }, [])

  if (error) {
    return <div>Error : {error.message}</div>;
  } else if (!items.result) {
    return <div>Loading...</div>;
    console.log("no item");
  } else {
    setUrls([urls, items]);
    console.log("items", items);
    console.log("urls", urls);
    return <ul> {items.result.short_link}</ul>;
  }
}


export default getShortenUrl;

I am kindof lost when it comes to state actually. I do not understand how I can create an array of urls and be able to use it in other components.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

执笏见 2025-01-16 09:38:43

这里可能有一些错误

      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )

将其更改为

.then((result) => {
          setItems(result);
          setUrls([...urls, result])
})
.catch((error) => {
          setError(error);
})

并且还删除行 setUrls([urls, items]);

You may have some mistakes here

      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )

Change it into

.then((result) => {
          setItems(result);
          setUrls([...urls, result])
})
.catch((error) => {
          setError(error);
})

And also remove the line setUrls([urls, items]);

悟红尘 2025-01-16 09:38:43

如果您是反应新手,那么我们会为 API 调用获取加载状态,并且您在 else 中设置状态,并且当状态更新组件重新渲染时,因此在每个组件重新渲染时您都会更新状态,这会导致无限循环。试试这个

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  // const [items, setItems] = useState({}); // remove it because you are using urls and items state for same purposes
  const [loading,setLoading]=useState(false);

  useEffect(() => {
    setLoading(true);
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
    (result) => {
      // setItems(result); // remove it
      setUrls(result);
      setLoading(false);
    },
    (error) => {
      setError(error);
      setLoading(false);
    }
      )
  }, [])
      if(loading){
           return <div>Loading...</div>;
      }
  if (error) {
    return <div>Error : {error.message}</div>;
  } else {
    return <ul> {urls?.result?.short_link}</ul>;
  }
}


export default getShortenUrl;

If you are new to react then we make Loading state for API Call fetch and you are setting state in else and when state updates component re-renders so on every component re-render you are updating state which is causing infinite loop. Try this

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  // const [items, setItems] = useState({}); // remove it because you are using urls and items state for same purposes
  const [loading,setLoading]=useState(false);

  useEffect(() => {
    setLoading(true);
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
    (result) => {
      // setItems(result); // remove it
      setUrls(result);
      setLoading(false);
    },
    (error) => {
      setError(error);
      setLoading(false);
    }
      )
  }, [])
      if(loading){
           return <div>Loading...</div>;
      }
  if (error) {
    return <div>Error : {error.message}</div>;
  } else {
    return <ul> {urls?.result?.short_link}</ul>;
  }
}


export default getShortenUrl;
半夏半凉 2025-01-16 09:38:43

尝试使用条件渲染而不是 if else 语句:

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  const [items, setItems] = useState({});

  useEffect(() => {
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )
  }, [])

return (

         <>
             {error&& <div>Error : {error.message}</div>}
             {!items.result && <div>Loading...</div> }
             {items.result &&  <ul> {items.result.short_link}</ul>}
        </>
   )
 
}


export default getShortenUrl;

Try to use a conditional rendering instead of if else statement:

import React, { useState, useEffect } from 'react';

function getShortenUrl() {
  const [urls, setUrls] = useState([])
  const [error, setError] = useState(null);
  const [items, setItems] = useState({});

  useEffect(() => {
    fetch("https://api.shrtco.de/v2/shorten?url=https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array")
      .then(res => res.json())
      .then(
        (result) => {
          setItems(result);
        },
        (error) => {
          setError(error);
        }
      )
  }, [])

return (

         <>
             {error&& <div>Error : {error.message}</div>}
             {!items.result && <div>Loading...</div> }
             {items.result &&  <ul> {items.result.short_link}</ul>}
        </>
   )
 
}


export default getShortenUrl;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文