2 回答

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超5個(gè)贊
你想使用useEffect鉤子。嘗試類似的東西:
? useEffect(() => {
? ? firebase.database().ref().on('value', (snapshot) => {
? ? ? const obj = snapshot.val();
? ? ? const arrData = [];
? ? ? Object.values(obj.Notas).forEach(e =>?
? ? ? ? arrData.push({ title: e.evento, date: e.fecha }));
? ? ? setName(arrData);
? ? });
? }, firebase.database().ref().on('value'));
您在上面的代碼中顯示的問題是每次調(diào)用時(shí)setName()都會(huì)重新渲染組件(這是 React 返回的一個(gè)特殊函數(shù),用于更改組件狀態(tài)并重新渲染)。當(dāng)它重新渲染時(shí),setName()再次調(diào)用,從而導(dǎo)致重新渲染中的無限循環(huán)。
useEffect()不會(huì)在重新渲染時(shí)運(yùn)行,而是僅在檢測到數(shù)據(jù)已更改時(shí)運(yùn)行。在這種情況下,它會(huì)檢查是否firebase.database().ref().on('value')已更改,如果是,則運(yùn)行代碼useEffect()并重新渲染。
順便說一句,可以應(yīng)用一個(gè)小的優(yōu)化是使用局部變量來存儲(chǔ)過程中的值。然后setName()只調(diào)用一次。因?yàn)槿缜八?,每次調(diào)用這個(gè)特殊函數(shù),都可能導(dǎo)致重新渲染。所以你只想在完成所有中間過程后調(diào)用它一次。或者更好的是,以函數(shù)式風(fēng)格進(jìn)行:
? useEffect(() => {
? ? firebase.database().ref().on('value', (snapshot) => {
? ? ? setName(Object.values(snapshot.val().Notas).map(e =>?
? ? ? ? { title: e.evento, date: e.fecha }));
? ? });
? }, firebase.database().ref().on('value'));

TA貢獻(xiàn)1995條經(jīng)驗(yàn) 獲得超2個(gè)贊
你有兩個(gè)問題:
firebase 在反應(yīng)組件中創(chuàng)建監(jiān)聽器。
在里面調(diào)用 setName
Array.prototype.forEach
;
我會(huì)告訴你循環(huán)在哪里。
組件被渲染;
組件創(chuàng)建狀態(tài)
[name, setName]
;組件調(diào)用
firebase.database().ref().on('value', callback)
;Callback從firebase獲取數(shù)據(jù),通過forEach按鍵進(jìn)行迭代;
在您調(diào)用 forEach 的第一次迭代中
setName
;setName
調(diào)用重新渲染;走到
3
臺(tái)階;
解決方案:
function OwnComponent(props) {
const [date, setFecha] = useContext(Contexto);
const [name, setName] = useState([]);
const dateClick = React.useCallback((arg) => {
setFecha(arg.dateStr);
}, [setFecha]);
React.useEffect(() => {
const unsubscribe = firebase.database().ref(/* you can pass 'Notas'
here */).on('value', (snapshot) => {
setName(Object.values(snapshot.val().Notas/* you can remove .Notas here */).map(
({ evento: title, fecha: date }) => ({ title, date })
));
});
return () => {
unsubscribe();
};
}, []);
return (
<FullCalendar
plugins={[dayGridPlugin, listPlugin, interactionPlugin]}
initialView="dayGridMonth"
dateClick={dateClick}
events={name}
/>
);
}
添加回答
舉報(bào)