[英]React useEffect not running after state change
我正在查詢 Firebase 實時數據庫,將結果保存到 state 然后渲染結果。
我的數據沒有顯示,因為頁面在獲得數據之前正在呈現。 我不明白的是為什么
useEffect(() => {
for (var key in projects) {
var projectData = {
title: projects[key].title,
description: projects[key].description,
};
result.push(<Project props={projectData} />);
}
}, [projects]);
一旦項目 state 更改被觸發,填充數組並觸發條件渲染行,我的使用效果就不會運行。
我在這里錯過了什么?
const [projects, setProjects] = useState();
const { user } = useUserAuth();
const result = [];
const dbRef = ref(db, `/${user.uid}/projects/`);
useEffect(() => {
onValue(dbRef, (snapshot) => {
setProjects(snapshot.val());
});
}, []);
useEffect(() => {
for (var key in projects) {
var projectData = {
title: projects[key].title,
description: projects[key].description,
};
result.push(<Project props={projectData} />);
}
}, [projects]);
return (
<>
{result.length > 0 && result}
</>
);
};
result
也應該是一個狀態!
現在每個重新渲染result
都被設置為[]
。 因此,當 useEffect 確實啟動時,隨后的重新渲染將再次將result
設置為[]
。
這不應該是useEffect
。 效果在渲染后運行,但您試圖將<Project>
元素放在頁面上,這必須在渲染期間發生。 只需在組件主體中執行即可:
const [projects, setProjects] = useState();
const { user } = useUserAuth();
const dbRef = ref(db, `/${user.uid}/projects/`);
useEffect(() => {
onValue(dbRef, (snapshot) => {
setProjects(snapshot.val());
});
}, []);
const result = [];
for (var key in projects) {
var projectData = {
title: projects[key].title,
description: projects[key].description,
};
result.push(<Project props={projectData} />);
}
return (
<>
{result.length > 0 && result}
</>
);
result.push
不會就地改變result
。 相反,它會使用新值創建數組的副本。
作為解決方案,您可以通過將result
提升到 state 變量中來使當前代碼正常工作,如下所示:
const [result, setResult] useState([])
...
useEffect(() => {
for (var key in projects) {
...
setResult([...result, <Project props={projectData} />])
}
}, [result, projects]);
然而,這個解決方案會導致無限循環......
我的建議是重做一些邏輯並使用projects
來渲染您的Project
組件,而不是創建一個變量來封裝您的渲染組件。 像這樣:
const [projects, setProjects] = useState();
const { user } = useUserAuth();
const dbRef = ref(db, `/${user.uid}/projects/`);
useEffect(() => {
onValue(dbRef, (snapshot) => {
setProjects(snapshot.val());
});
}, []);
return (
<>
{projects.length > 0 && projects.map(project=>{
var projectData = {
title: projects[key].title,
description: projects[key].description,
};
return <Project props={projectData} />
})}
</>
);
};
你的組件沒有重新渲染,因為反應不關心你的result
變量被填充。
像這樣將其設置為 state: const [result, setResult] = useState([]);
然后使用 map 返回數組的每一項作為 desire 組件:
{result.length > 0 && result.map((data, index) => <Project key={index} props={data} />)}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.