簡體   English   中英

React Hook 未使用 useEffect 設置

[英]React Hook not setting with useEffect

我正在使用useEffect從 Trello 獲取一些數據並設置一些狀態。 首先,我拿起我正在尋找的卡片並調用setCardsetCardLocation 一切正常。 然后我進入我的else案例,無論我做什么setPublishDate永遠不會被設置,循環繼續運行。 為什么所有這些其他鈎子都可以工作,而我的最后一個沒有? 謝謝。

export default function Home(props) {
  const [performedFetch, setPerformedFetch] = useState(false);
  const [slug, setSlug] = useState(null);
  const [cardLocation, setCardLocation] = useState(1);
  const [card, setCard] = useState(null);
  const [publishDate, setPublishDate] = useState(null);

  const key = ''; // imagine these are here
  const token = '';

  useEffect(() => {
    setSlug(
      new URLSearchParams(window.location.search).get('slug')
    );

    if (!performedFetch && !!slug) {
      fetch(`https://api.trello.com/1/lists/${listId}/cards?key=${key}&token=${token}`)
          .then(response => response.json())
          .then(data => {
            setPerformedFetch(true);

            data.forEach((c, index) => {
              if (c.desc.includes(slug)) {                    
                setCard(c)
                setCardLocation(index + 1)
              } else if (!publishDate && index > cardLocation) { 
                console.log(publishDate); // why is this always null?? also runs multiple times

                const name = c.name;
                const frontHalf = name.split("/")[0].split(" ");
                const month = frontHalf[frontHalf.length - 1];
                const day = name.split("/")[1].split(")")[0];
                setPublishDate(`${month}/${day}`);
              }
            });
        });
    }
  });

這是因為通常react states更新是異步的,並且在您檢查slug時它還沒有設置

你需要做這樣的事情:

function Home(props) {
  const [performedFetch, setPerformedFetch] = useState(false);
  const [slug, setSlug] = useState(null);
  const [cardLocation, setCardLocation] = useState(1);
  const [card, setCard] = useState(null);
  const [publishDate, setPublishDate] = useState(null);

  const key = ""; // imagine these are here
  const token = "";

  useEffect(() => {
    setSlug(new URLSearchParams(window.location.search).get("slug"));
  });

  useEffect(() => {
    console.log(slug)
    if (!performedFetch && !!slug) {
      fetch(`https://api.trello.com/1/lists/${listId}/cards?key=${key}&token=${token}`)
          .then(response => response.json())
          .then(data => {
            setPerformedFetch(true);

            data.forEach((c, index) => {
              if (c.desc.includes(slug)) {                    
                setCard(c)
                setCardLocation(index + 1)
              } else if (!publishDate && index > cardLocation) { 
                console.log(publishDate); // why is this always null?? also runs multiple times

                const name = c.name;
                const frontHalf = name.split("/")[0].split(" ");
                const month = frontHalf[frontHalf.length - 1];
                const day = name.split("/")[1].split(")")[0];
                setPublishDate(`${month}/${day}`);
              }
            });
        });
    }
  }, [slug, performedFetch])
}

正如@TaghiKhavari已經提到的,您應該有兩個useEffects多個效果來分離關注點)。

此外,通過提供依賴數組作為useEffect第二個參數跳過效果來優化性能也很重要。 因此,只有當它的任何依賴項發生變化時,效果才會重新運行。

slug的第一個效果:

useEffect(() => {
  setSlug(
    new URLSearchParams(window.location.search).get('slug')
  );
}, []) // Note: Remove "[]" if you want to set slug at each update / render Or keep it if you want to set it only once (at mount)

獲取和設置卡片和其他詳細信息的第二個效果:

useEffect(() => {
  if (!performedFetch && slug) {
    fetch(
      `https://api.trello.com/1/lists/${listId}/cards?key=${key}&token=${token}`
    )
      .then((response) => response.json())
      .then((data) => {
        setPerformedFetch(true)

      // Note: if there can be only ONE matching card
      const index = data.findIndex((card) => card.desc.includes(slug))
      if (index > -1) {
        const card = data[index]
        setCard(card)
        setCardLocation(index + 1)
        const name = card.name
        const frontHalf = name.split('/')[0].split(' ')
        const month = frontHalf[frontHalf.length - 1]
        const day = name.split('/')[1].split(')')[0]
        setPublishDate(`${month}/${day}`)
      }

      // Setting State in a LOOP? is a problem
      /*
      data.forEach((card, index) => {
        if (card.desc.includes(slug)) {
          setCard(card)
          setCardLocation(index + 1)
        } else if (!publishDate && index > cardLocation) {
          const name = card.name
          const frontHalf = name.split('/')[0].split(' ')
          const month = frontHalf[frontHalf.length - 1]
          const day = name.split('/')[1].split(')')[0]
          setPublishDate(`${month}/${day}`)
        }
      })*/

    })
  }
}, [slug, performedFetch])

設置狀態可能是異步的以提高性能

因此,您不應像當前那樣在循環中設置狀態。 如果您必須遍歷循環並在 state 中設置數組的全部或少數元素,您可以循環遍歷數組並將所有相關項push送到本地數組變量中,並在循環結束后將其設置為 state。 希望能幫助到你!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM