首页 > 解决方案 > component not reading hook state properly

问题描述

I have an button (h1) component that has an onclick handler (handleDateLabelClick) that changes the state to decide whether or not a calendar is visible or not. Working properly, it should change the state to whatever the opposite currently is. Currently, clicking the button correctly causes the calendar to appear, but clicking the same button again does not cause the calendar to disappear. I've added a console log to the handleDateLabelClick function to see what is being read, and each time the calendarOpen state is false. This gets even more interesting when I observe in devtools that the state is operating correctly (true when open, false when closed). Here is my code (BookCard is parent of Calendar):

BookCard

const BookCard = ({
   ...props
}) => {
const [calendarOpen, setCalendarOpen] = useState(false)

const handleDateLabelClick = () => {
    setCalendarOpen(!calendarOpen)
}

<DateWrapper>
    <DateHeading onClick={handleDateLabelClick} level={4}>
        {parsedDate.toLocaleDateString('en-US', dateFormat)}
    </DateHeading>
    <Calendar
        handleChooseDate={handleChooseDate}
        calendarOpen={calendarOpen}
        setCalendarOpen={setCalendarOpen}
        {...props}
    />
</DateWrapper>

Calendar

const EnhancedCalendar = ({
  handleChooseDate,
  calendarOpen,
  setCalendarOpen,
  ...props
}) => {

  EnhancedCalendar.handleClickOutside = () => setCalendarOpen(false)

  return (
    <StyledCalendar
      calendarOpen={!!calendarOpen}
      showNeighboringMonth
      minDetail="month"
      onClickDay={handleChooseDate}
      activeStartDate={props.experienceDate}
      tileDisabled={({ activeStartDate, date, view }) => date < new Date()}
      tileDisabled={({ activeStartDate, date, view }) => {
        const availabilitiesForCurrentDate = getTimesForCurrentDate(date, props.detail.availabilities)
        return (
          !availabilitiesForCurrentDate.length
        )
      }}
    />
  )
}

const clickOutsideConfig = {
  handleClickOutside: () => EnhancedCalendar.handleClickOutside
}

export default onClickOutside(EnhancedCalendar, clickOutsideConfig)

enter image description here

标签: reactjs

解决方案


As you said in your comment:

I have a hook in Calendar that detects if there is a click outside of the calendar. it is executed at that point from within Calendar. And you found the bug spot on!! thank you! The question remains though, how can I keep this functionality without the current bug

I think your Calendar is fighting with your title.

To fix it easily, you could conditionally render your Calendar:

<DateWrapper>
    <DateHeading onClick={handleDateLabelClick} level={4}>
        {parsedDate.toLocaleDateString('en-US', dateFormat)}
    </DateHeading>
    {calendarOpen ? <Calendar
        handleChooseDate={handleChooseDate}
        calendarOpen={calendarOpen}
        setCalendarOpen={setCalendarOpen}
        {...props}
    /> : null }
</DateWrapper>

推荐阅读