代码之家  ›  专栏  ›  技术社区  ›  ReactNoob

fullcalendar react event单击模式使用状态设置event.id不工作

  •  0
  • ReactNoob  · 技术社区  · 2 年前

    问题背景: 目前使用FullCalendar v6.1.8和react-Bootstrap 5.2.3来显示API JSON url中的事件(无论是否使用Axios)。日历和活动加载得很好。 但是,使用eventClick设置模态的布尔显示状态,并将单个事件数据设置为state,会导致FullCalendar重新蚀刻。 在模式显示的背景屏幕上,背景事件随着重新蚀刻的发生而跳跃,这非常混乱。 因此,为了控制数据的获取,我将代码改为使用Axios。然而,当数据通过handleClick从FullCalendar返回时,我无法获得事件.id,因为它返回“未定义”,此后在随后的单击中,setEventId()可以工作,但它使用前一个事件的id。我认为我缺少了一种方法来合并某种钩子、useState或useMemo来等待循环,FullCalendar加载-->getEventsData()-->完整日历事件点击。但我花了三天时间寻找答案,测试各种代码,但我还是没能完全理解。

    故障排除: 当然,我搜索了SO和网络,查看了类似的报告,但很明显,我对React和FullCalendar的了解还不足以解决这个问题。如果我不能解决它,我可能不得不放弃FullCalendar。 在代码中,我已经将Json API提供给事件、eventSources,但refetch仍然发生。 所以,我想我会给FullCalendar提供一个函数。我先用一个简单的函数,然后用Axios和useEffect来做。 使用Axios和useEffect,我可以有效地控制提取和重新蚀刻。但现在的问题是,当FullCalendar从“eventClicked”返回数据时,我无法使用useState()将单个数据事件设置为常量。

    const Calendar = () => {
    
      const[URL, setURL] = useState("events")
      const[error, setError] = useState("")
      const[loading, setLoading] = useState(false)
      const[isModalOpen, setIsModalOpen] = useState(false)
      const[eventId, setEventId] = useState([])
      const[events, setEvents] = useState([])
    
      const[urlParms, setUrlParms] = useState({
        start: new Date(),
        end: new Date().tosISOString(),
      })
    
      useEffect(() => {
        getEventsData()
      }, [URL, urlParms])
    
      const getEventsData = async function () {
        setLoading(true)
        urlParms.start.setDate(0)
        try {
          const response = await 
                  axiosAPI.get(URL + 
                  `/?start=${urlParms.start.toISOString()
                   &end=${urlParms.end}}`)
          if (response && response.data) {
              setEvents(response.data)
              setLoading(false)
          }
        } catch (error) {
            console.log(error)
        }
      }
    
      const reservations = useMemo(()  => {
        let filteredResult = []
        if (events !== undefined) {
           filteredResult = events
        }
        return filteredResult
      }, [events])
    
      function handleEventClick(calData) {
        console.log(calData.event.id) /* This outputs fine the id of clicked event */
        setEventId(calData.event.id) /* This assignment fails the first time,
                                        thereafter it assigns the prior id. */
        console.log(eventId)         /* This outputs blank the first time */ 
      }
    
      return (
        <div>
         <FullcAlendar
          /* Other basic options are set here. Omitted for brevity. */
           events={reservations}
           eventClick={(calData) => handleEventClick(calData)}
         />
        </div>
       )
    
    
    }
    
    1 回复  |  直到 2 年前
        1
  •  0
  •   Jason Ming    2 年前

    function handleEventClick(calData) {
        console.log(calData.event.id) /* This outputs fine the id of clicked event */
        setEventId(calData.event.id) /* This assignment is succeeded */
        console.log(eventId)         /* But you will still see the prev eventId, because React don't update states immediately */
    }
    
    // If you want to do something after setting new state, you can use useEffect to track the new state.
    useEffect(() => {
      console.log(eventId); // Updated eventId
    }, [eventId];