反应:UI 应用过滤器时,dhtmlx-gantt 库无法正确绘制

React: UI not painted correctly with dhtmlx-gantt library when applied with filters

我正在使用 Reactdhtmlx-gantt 库来创建甘特图。我在将过滤器功能与 useEffect/useLayoutEffect 生命周期一起使用时遇到了问题。

要点是浏览器在某些情况下 painting/rendering 屏幕上的 UI 不正确。

启动状态加载屏幕如下所示:
6 任务

过滤后应该是这样的:
过滤掉持续时间 > 4

后应该剩下 5 个任务

但事实是这样的:
剩下 5 个任务,但显示的是空行而不是 "refreshing"(不确定这是否是正确的术语)

我创建了一个 github repo,其中包含描述问题的不同场景,以及如何重现这些问题。有关如何 运行 示例的更多信息,请参见 README.md。如果需要提供更多信息,请告诉我。

示例 1:使用条件渲染会导致绘画问题 UI 更改
示例 2:打开和关闭 smart_rendering 配置导致绘制问题 UI 更改
示例 3:使用完全相同的代码在父组件和子组件中调用函数会导致绘制问题 UI

我想要的结果是能够正确呈现 UI,无论此过滤数据的代码是否在父组件或子组件上 运行。

我还应该提一下,解决方法是在 onBeforeTaskDisplay 事件中使用 if (document.querySelector(".gantt_grid")) gantt.render(); 而不是 gantt.refreshData(),然后将正确绘制 UI 更改。但我仍然想了解为什么会发生这种情况。在使用 React 生命周期等方面我有没有做错什么。

谢谢。

在您的代码中 gantt.refreshData() 之后尝试 gantt.render()

    useEffect(() => {
        const onBeforeTaskDisplay = gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
            console.log("filters", task.text, filter)
            if (filter && task.duration > 4) {
                return false;
            }
            return true;
        });
        gantt.refreshData();
        gantt.render();

        // This should have been here
        return () => {
            gantt.detachEvent(onBeforeTaskDisplay);
        }
    }, [filter])

您的代码看起来不错,应该可以正常工作。

问题在dhtmlxGantt端,已经确认,目前在dev分支修复。

BUG本身是由v6.2.0引入的新的智能渲染机制引起的。 它缓存先前计算的任务位置以最小化计算。在某些情况下,当甘特图实例已被多次初始化时,它不会在必要时使缓存失效。因此,任务显示在与应用过滤之前相同的位置(因此第一个任务所在的空白行)。

简而言之,该问题将在下一个错误修复更新 - v6.2.6 中修复。

如果一切顺利,将于明天(2019-09-19)发布