[英]How do you push a UI update to a javascript frontend?
所以我正在構建一個簡單的反應應用程序,它獲取一堆圖像並將它們顯示為卡片。
目的是顯示一條信息消息,直到所有圖像都加載完畢,然后再次刪除通知。
const App = () => {
const [cardInfo, setCardInfo] = useContext(CardInfoContext)
useEffect(() => {
fetchData(setCardInfo)
}, [])
useEffect(() => {
const app = document.querySelector('.app')
for(const child of app.children){
app.removeChild(child)
}
const loadingNotice = document.createElement('h1')
loadingNotice.innerHTML = "Fetching data ..."
app.appendChild(loadingNotice) //<-- this never shows up
cardInfo.forEach( info => {
const img = document.createElement('img')
img.src = info.image
app.appendChild(img)
})
app.removeChild(loadingNotice)
}, [cardInfo])
return (
<>
<div className="app">
<h1>Fetching data...</h1>
</div>
</>
)};
相反,應用程序會一直保持空白,直到所有圖像都加載完畢,然后一次顯示所有圖像——但從來沒有加載通知。
我可以以某種方式將加載指示器更改“推送”到獨立於渲染的 rest 的 UI 嗎?
我嘗試的另一件事是
const App = () => {
const [cardInfo, setCardInfo] = useContext(CardInfoContext)
useEffect(() => {
fetchData(setCardInfo)
}, [])
useEffect(() => {
const app = document.querySelector('.app')
if(!cardInfo) return
const loadingNotice = app.querySelector(".loadingNotice")
loadingNotice.style.display = 'block' //<-- this never shows up
cardInfo.forEach( info => {
const img = document.createElement('img')
img.src = info.image
app.appendChild(img)
})
loadingNotice.style.display = 'none'
}, [cardInfo])
return (
<>
<div className="app">
<h1 className="loadingNotice">Fetching data...</h1>
</div>
</>
)}
這將是不正確的,因為我確實需要刪除所有圖像,至少,但即使只顯示加載通知幾分之一秒,然后組件變為空白,直到可以顯示所有圖像。
useEffect
觀察cardInfo
何時更改,而不是渲染觸發后發生的時間。 您可以改用useLayoutEffect
。
...但它會在所有 DOM 突變后同步觸發。 使用它從 DOM 中讀取布局並同步重新渲染。 在 useLayoutEffect 中安排的更新將在瀏覽器有機會繪制之前同步刷新。
順便說一句,我不會將直接 DOM 操作與 React 結合起來以避免這樣的問題(以及其他原因)
就像是
const App = () => {
const [isLoadgin, setIsLoading] = useState(true)
const [cardInfo, setCardInfo] = useContext(CardInfoContext)
useEffect(() => {
fetchData(result => {
setCardInfo(result);
setIsLoading(false);
})
}, [])
return (
<>
<div className="app">
{isLoading && <h1 className="loadingNotice">Fetching data...</h1>}
{
cardInfo.map(card => <img src={card.image} />)
}
</div>
</>
)}
您需要條件渲染,而不是在 useEffect 中嘗試的所有 DOM 操作。
...
return(
<>
<div className="app">
{ !cardInfo ? <h1 className="loadingNotice">Fetching data...</h1> : <Cards info={cardInfo} /> }
</div>
</>
)
注意:我假設您有類似<Cards>
組件來顯示卡片詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.