[英]React Hook not setting with useEffect
我正在使用useEffect
從 Trello 獲取一些數據並設置一些狀態。 首先,我拿起我正在尋找的卡片並調用setCard
和setCardLocation
。 一切正常。 然后我進入我的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.