React简单的useEffect无限循环

React simple useEffect infinit loop

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

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=
      .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 数组并能够在其他组件中使用它。

尝试使用条件渲染而不是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=
      .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;

如果您是 React 新手,那么我们会为 API 调用 fetch 设置加载状态,您在 else 中设置状态,当状态更新组件 re-renders 时,每个组件都会如此 re-render您正在更新导致无限循环的状态。试试这个

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=
      .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;

这里可能有一些错误

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

改成

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

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