首页 > 解决方案 > React Big Calendar - 自定义视图中的自定义道具

问题描述

我在 react-big-calendar 库中有一年的自定义视图。

<Calendar
  localizer={localizer}
  events={events || []}
  startAccessor="start"
  endAccessor="end"
  defaultView="year"
  views={{
    year: YearView
  }}
  components={{
    toolbar: props => (<Toolbar {...props} />)
  }}
/>

我需要在 YearView 中传递另一个道具,我试图这样传递

<Calendar
  localizer={localizer}
  events={events || []}
  startAccessor="start"
  endAccessor="end"
  defaultView="year"
  views={{
    year: props => (
      <YearView
        {...props}
        onCreateOrEdit={onCreateOrEdit}
      />
    )
  }}
  components={{
    toolbar: props => (<Toolbar {...props} />)
  }}
/>

但不起作用,弹出错误“TypeError:无法读取未定义的属性'title'”。另一个解决方案是使用 React Context,但在我的情况下,这不是一个选项,因为我使用的是 monorepo 并且组件位于另一个应用程序文件夹中。

YearView 组件

    export const YearView = React.memo(({
      events, 
      onCreateOrEdit, 
      range, 
      date, 
      action, 
      localizer, 
      ...props 
    }) => {
    const [modalIsOpen, setModalIsOpen] = React.useState(false)
    const [modalTitle, setModalTitle] = React.useState('')
    const [isEventosDoDia, setIsEventosDoDia] = 
      React.useState(false)
    const [dialogEventsArray, setDialogEventsArray] = 
      React.useState(events);
    const [months, setMonths] = React.useState([])

    React.useEffect(() => {
     const monthsArray = []
     const firstMonth = dates.startOf(date, 'year')
     
     for (let i = 0; i < 12; i++) {
       monthsArray.push(
        <Calendar
          key={i + 1}
          date={dates.add(firstMonth, i, 'month')}
          eventosDoMes={
            events.filter(
              meses => meses.mes === getMonthByNumber(i)
          )}
          modalTitle={modalTitle}
          setModalTitle={(title) => setModalTitle(title)}
          listaDeEvento={dialogEventsArray}
          setListaDeEvento={(
            eventos) => setDialogEventsArray(eventos
          )}
          isEventosDoDia={isEventosDoDia}
          setIsEventosDoDia={(
            eventosDia) => setIsEventosDoDia(eventosDia
          )}
          modalIsOpen={modalIsOpen}
          setModalIsOpen={(isOpen) => setModalIsOpen(isOpen)}
        />
      )
    }

     setMonths(monthsArray)
    }, [date, isEventosDoDia, modalIsOpen, modalTitle])

    return (
      <YearContainer {...props}>
        <EventsDialog
          isOpen={modalIsOpen}
          title={modalTitle}
          eventsList={dialogEventsArray}
          isEventosDoDia={isEventosDoDia}
          setModalIsOpen={(isOpen) => setModalIsOpen(isOpen)}
       />
           
       {months.map((month) => month)}
      </YearContainer>
    )
    })

    YearView.navigate = (date, action) => {
      switch (action) {
       case navigate.PREVIOUS:
        return dates.add(date, -1, 'year')

       case navigate.NEXT:
        return dates.add(date, 1, 'year')

       default:
        return date
     }
    }

    YearView.title = (date, { localizer }) => 
      localizer.format(date, 'YYYY')

以及 YearVew 文件中道具的 console.log。

"props": {
    "startAccessor": "start",
    "endAccessor": "end",
    "views": {
        "year": {
            "compare": null
        }
    },
    "popup": false,
    "step": 30,
    "drilldownView": "day",
    "titleAccessor": "title",
    "tooltipAccessor": "title",
    "allDayAccessor": "allDay",
    "resourceAccessor": "resourceId",
    "resourceIdAccessor": "id",
    "resourceTitleAccessor": "title",
    "longPressThreshold": 250,
    "dayLayoutAlgorithm": "overlap",
    "backgroundEvents": [],
    "length": 30,
    "getters": {},
    "components": {},
    "accessors": {},
    "doShowMoreDrillDown": true
}

标签: javascriptreactjsreact-hooksreact-big-calendar

解决方案


首先,我注意到您记住了 YearView 组件。这可能会导致创建和使用静态title方法出现问题。

我还注意到您将 prop 直接添加到views定义中的组件中,而不是作为Calendar自身的 prop。

<Calendar
  localizer={localizer}
  events={events || []}
  startAccessor="start"
  endAccessor="end"
  defaultView="year"
  onCreateOrEdit={onCreateOrEdit}
  views={{
    year: YearView
  }}
  components={{
    toolbar: Toolbar
  }}
/>

要知道的是,并非所有 Calendar 道具都传递给它的所有内部组件。您的自定义View组件可以将 prop 传递给它呈现的组件,但Calendar不能。它们被传递给当前View的渲染,但你永远无法访问Toolbar. 您可以通过阅读Calendar组件的render()方法的源代码看到这一点。


推荐阅读