React 的 useState 问题,太多的重新渲染

我正在将 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)

        })

    }, []);


回首忆惘然
浏览 233回答 2
2回答

慕田峪4524236

你想使用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 在反应组件中创建监听器。在里面调用 setName&nbsp;Array.prototype.forEach;我会告诉你循环在哪里。组件被渲染;组件创建状态[name, setName];组件调用firebase.database().ref().on('value', callback);Callback从firebase获取数据,通过forEach按键进行迭代;在您调用 forEach 的第一次迭代中setName;setName调用重新渲染;走到3台阶;解决方案:function OwnComponent(props) {&nbsp; const [date, setFecha] = useContext(Contexto);&nbsp; const [name, setName] = useState([]);&nbsp; &nbsp;&nbsp;&nbsp; const dateClick = React.useCallback((arg) => {&nbsp; &nbsp; setFecha(arg.dateStr);&nbsp; }, [setFecha]);&nbsp; &nbsp;&nbsp;&nbsp; React.useEffect(() => {&nbsp; &nbsp; const unsubscribe = firebase.database().ref(/* you can pass 'Notas'&nbsp;&nbsp;here */).on('value', (snapshot) => {&nbsp; &nbsp; &nbsp; setName(Object.values(snapshot.val().Notas/* you can remove .Notas here */).map(&nbsp; &nbsp; &nbsp; &nbsp; ({ evento: title, fecha: date }) => ({ title, date })&nbsp; &nbsp; &nbsp; ));&nbsp; &nbsp; });&nbsp; &nbsp; return () => {&nbsp; &nbsp; &nbsp; unsubscribe();&nbsp; &nbsp; };&nbsp; }, []);&nbsp; &nbsp;&nbsp;&nbsp; return (&nbsp; &nbsp; <FullCalendar&nbsp; &nbsp; &nbsp; plugins={[dayGridPlugin, listPlugin, interactionPlugin]}&nbsp; &nbsp; &nbsp; initialView="dayGridMonth"&nbsp; &nbsp; &nbsp; dateClick={dateClick}&nbsp; &nbsp; &nbsp; events={name}&nbsp;&nbsp; &nbsp; />&nbsp; );}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript