2 回答
TA贡献1875条经验 获得超5个赞
你想使用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'));
TA贡献1995条经验 获得超2个赞
你有两个问题:
firebase 在反应组件中创建监听器。
在里面调用 setName
Array.prototype.forEach
;
我会告诉你循环在哪里。
组件被渲染;
组件创建状态
[name, setName]
;组件调用
firebase.database().ref().on('value', callback)
;Callback从firebase获取数据,通过forEach按键进行迭代;
在您调用 forEach 的第一次迭代中
setName
;setName
调用重新渲染;走到
3
台阶;
解决方案:
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}
/>
);
}
添加回答
举报