我正在使用fullcalendar库来完成一个小项目,只为学习React js(我是新手(。当我从firebase上的实时数据库中获取数据时,我会尝试在日历中显示事件的名称(evento(和日期(fecha(,但当我使用setName((将数据放入数组name=[]
时,会出现一个错误,比如重新渲染,我不知道如何修复它……如果有人能帮助我,那就太好了!!
(很抱歉我英语不好(
感谢
这是错误和代码:
在此处输入图像描述
const [date, SetFecha] = useContext(Contexto)
const [name, setName] = useState([])
firebase.database().ref().on('value', (snapshot) => {
let obj = snapshot.val()
Object.values(obj.Notas).forEach(e => {
setName([...name, { title: e.evento, date: e.fecha }])
});
})
const DateClick = (arg) => {
SetFecha(arg.dateStr)
}
return (
<FullCalendar
plugins={[dayGridPlugin, listPlugin, interactionPlugin]}
initialView="dayGridMonth"
dateClick={DateClick}
events={name}
/>
)
解决方案
useEffect(() => {
firebase.database().ref().on('value', (snapshot) => {
let obj = snapshot.val()
let arr = []
Object.values(obj.Notas).forEach(e => {
arr.push({ title: e.evento, date: e.fecha })
});
setName(arr)
})
}, []);
您想要使用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'));
上面显示的代码中的问题是,每次调用setName()
时,都会重新渲染组件(这是React返回的一个特殊函数,用于更改组件状态并重新渲染(。当它重新渲染时,setName()
会被再次调用,从而在重新渲染中产生无限循环。
useEffect()
不会在重新渲染中运行,而是仅在检测到数据已更改时运行。在这种情况下,它会检查firebase.database().ref().on('value')
是否已更改,如果是,则在useEffect()
中运行代码并重新渲染。
更多内容可以在这里阅读。
顺便说一句,有一个小的优化可以应用是使用一个局部变量来存储过程中的值。然后只调用setName()
一次。因为如前所述,每次调用这个特殊函数时可能导致重新渲染。因此,当您完成所有中间过程时,您只想调用它一次。或者更好的是,以一种功能性的方式进行:
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'));
您有两个问题:
- firebase在react组件内部创建监听器
- 调用
Array.prototype.forEach
内部的setName
我会告诉你循环在哪里。
- 渲染组件
- 组件创建状态
[name, setName]
- 组件调用
firebase.database().ref().on('value', callback)
- 回调从firebase获取数据,并通过forEach按键进行迭代
- 在forEach内部的第一次迭代中,您调用
setName
setName
调用重新渲染- 进入CCD_ 14步骤
解决方案:
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}
/>
);
}