为了账号安全,请及时绑定邮箱和手机立即绑定

React Hook 未使用 use 设置Effect

React Hook 未使用 use 设置Effect

www说 2022-08-18 16:34:25
我用来从Trello获取一些数据并设置一些状态。首先,我拿起我要找的卡,然后打电话和.一切都很好。然后我进入我的案例,无论我做什么都不会被设定,循环继续运行。为什么所有这些其他钩子都有效,而我的最后一个钩子却不起作用?谢谢。useEffectsetCardsetCardLocationelsesetPublishDateexport 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}`);              }            });        });    }  });
查看完整描述

2 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

正如@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])

设置状态可能是异步的,以提高性能:


因此,您不应像当前所做的那样在循环中设置状态。如果必须循环访问并将数组的所有或几个元素设置为状态,则可以循环遍历数组和局部数组变量中的所有相关项,并在循环结束后将其设置为状态。希望它有帮助!push


查看完整回答
反对 回复 2022-08-18
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

这是因为通常以异步方式更新,并且在您检查它时尚未设置react statesslug


你需要做这样的事情:


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])

}


查看完整回答
反对 回复 2022-08-18
  • 2 回答
  • 0 关注
  • 190 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号