首页 > 解决方案 > 使用 vis-timeline 模板时访问状态或道具的问题

问题描述

我正在尝试使用 vis-timeline 模板函数来呈现反应组件。这主要按预期工作,除了我的模板函数无法访问道具,我的模板组件也无法访问应用程序状态。

这是我的反应时间线组件

const Gantt = (props) => {
    let timeline: visTimeline.Timeline | undefined = undefined;
    let timelineNode: HTMLDivElement | null = null;

    const timelineRef = React.useRef<visTimeline.Timeline | undefined>(timeline);

    const createTimeline = () => {
        if (timelineNode && !timelineRef.current) {
            timeline = new visTimeline.Timeline(
                timelineNode,
                items ?? [],
                groups,
                {
                    template: wrappedTemplateFunc,
                }
            );

            timelineRef.current = timeline;
        } else if (!loaded) {
            deferredLoad();
        }
    }

    const wrappedTemplateFunc = (item: visTimeline.TimelineItem, element: any) => {
        if(!item) {
            return '';
        }

        const schedItem = findTaskItem(item);

        if (props.itemTemplate) {
            ReactDOM.createPortal(
                ReactDOM.render(<props.itemTemplate itemId={item.id} />, element) as React.ReactNode,
                element,
                (() => {
                  timelineRef.current?.redraw();
                }) as any
            );

            return element.innerHtml;
        }

        element.id = item.id;

        return item.type === "background"
                   ? `<span>${item.content}</span>`
                   : item.content;
    }

    // so that a new iterator function isn't created per call to wrappedTemplateFunc
    const findTaskItem = (item: visTimeline.TimelineItem): typeDefs.TaskItem | undefined => {
        if (!props.data) {
            return undefined;
        }

        for (let i = 0, dataCount = props.data.length; i < dataCount; i++) {
            if (props.data[i].Id === item.id) {
                return props.data[i];
            }
        }
        return undefined;
    }

    return (
        <div ref={el => (timelineNode = el)} />
    );
}

props 的一部分是要显示的时间线的数据项数组。我希望该数组包含提供给时间线的项目,但 props.data 数组始终为空。

这是我的模板组件

const GanttItemTemplate = (props: GanttItemTemplateProps) => {
    const { state } = useContext(AppContext);

    const [taskId, setTaskId] = useState<string>(props.itemId);
    const [task, setTask] = useState<EnersightTaskItem>();

    useEffect(() => {
        setTaskId(props.itemId);
    }, [props.itemId]);

    useEffect(() => {
        console.log(state.enersightTaskData.data);
        
        setTask(state.enersightTaskData?.data.find((item: EnersightTaskItem) => 
            item.Id === props.itemId));
    }, [taskId, state.enersightTaskData.data]);

    return (
        <span>{task?.Id}</span>
    );
}

我还希望能够从组件内部访问状态。我认为这是由于模板函数的调用方式或某种陈旧的闭包造成的。有谁知道如何实现这个或类似的东西?

标签: reactjstypescriptvis.js

解决方案


推荐阅读