0

我正在使用 React Calendar https://www.npmjs.com/package/react-calendar并且我正在使用他们的 ref 道具来操作日期按钮,以便我可以将自定义功能直接添加到日历 DOM(只有真正的方式这样做我认为因为他们的道具是有限的。如果你们知道更好的方法,请告诉我,这样我就可以停止使用这种方法了!顺便说一句,我知道添加 CSS 的 tileClassName 存在,但我想要一些我可以的悬停功能'似乎并没有把我的头放在 tileClassName 中)。react 日历 ref 是对整个日历 div 的引用,而不是 React 组件 :( 。

react-calendar/src/YearView/Calendar.jsx 中的 Calendar.jsx

return (
      <div
        className={mergeClassNames(
          baseClassName,
          selectRange && valueArray.length === 1 && `${baseClassName}--selectRange`,
          showDoubleView && `${baseClassName}--doubleView`,
          className,
        )}
        ref={inputRef}
      >
        {this.renderNavigation()}
        <div
          className={`${baseClassName}__viewContainer`}
          onBlur={selectRange ? onMouseLeave : null}
          onMouseLeave={selectRange ? onMouseLeave : null}
        >
          {this.renderContent()}
          {showDoubleView && this.renderContent(true)}
        </div>
      </div>
    );

现在在我的自定义日历 js 中,在每个 useEffect 上,我都进行了设置,以便当前 Ref 的单击下一个导航按钮更改依赖于 useEffect 的月份状态,以便可以再次重新触发 useEffect。 在此处输入图像描述

const MainCalendar = () => {
  const [month, setMonth] = useState(0)
  const ref = React.useRef()

useEffect(() => {
    // arrows in ref Change State
    ref.current.getElementsByClassName('react-calendar__navigation__arrow react-calendar__navigation__next-button')[0].onclick = () => {
      setMonth(month + 1)
      return
    }
    console.log(ref.current)
    console.log(ref.current.getElementsByClassName('react-calendar__navigation__label')[0].children[0].textContent)
}, [month])

return(
     <Calendar
          inputRef={ref}/>)
}

现在,当我单击这个用红色圈起来的箭头按钮时,重新触发确实发生了,因为控制台再次记录了这两个项目,但是如果你检查我的 useEffect 函数,我正在打印那个 ref.Current 中的 ref.Current 和一个 ELEMENT . 我选择的这个元素是标题月/年(例如:上图中的 2021 年 7 月)。现在,控制台正在使用新的 2021 年 8 月日期正确打印当前的 ref DOM(第一个控制台打印)(因为导航按钮向上移动了一个月),但是当我使用 getElementByClassName 访问 ref DOM 时,它似乎正在打印以前的 Ref 元素(第二个控制台打印)而不是我需要的当前 Ref 元素标题。(例如:打印 2021 年 7 月,而应该是 2021 年 8 月)

在此处输入图像描述

如何修复它,以便在 useEffect 中访问的 Ref 元素是最新信息(基本上是来自记录的 ref.current 的信息)?尽管打印 ref.current 显示 2021 年 8 月,但似乎并非如此。我需要它在 useEffect 重新触发后恰好是最新的,以便我可以根据当前呈现的标题设置条件,但我可以由于这种困境,现在不要这样做。使这些 ref 元素保持最新的最佳方法是什么?谢谢

4

1 回答 1

0

我找到了解决方案。

async function waitForDate(i) {
    function dateChanged() {
      return new Promise(resolve => {
        const observer = new MutationObserver(() => {
          resolve()
        })
        var config = { characterData: true, attributes: false, childList: false, subtree: true }

        observer.observe(ref.current.getElementsByClassName('react-calendar__navigation__label')[0].children[0], config)
      })
    }

    await dateChanged()

    setMonth(month + i)
  }

我在 useEffect 的 onclick 方法中调用了这个 waitForDate 函数。

我创建了一个异步函数,它观察并等待 ref 元素更改 title 元素。一旦触发,我就使用Effect 重新渲染整个事物。

似乎我之前的解决方案没有考虑到当前的 Ref 可能在单击导航按钮并且重新触发 useEffect 后仍然过时。所以我必须先等待并确认它已经改变了我使用的这个功能。

于 2021-07-22T05:40:17.173 回答