React Lazy Load Component into React Grid Layout 适用于 1 但不适用于多个

问题描述

我正在尝试将 UI 模块动态加载到 React 网格布局 (https://github.com/STRML/react-grid-layout) 中,但是我遇到了以下问题:

这是我加载组件的代码

App.tsx

const App = () => {
  const [modules,setModules] = useState<JSX.Element[]>([(<WeatherModule/>)]); //<-- NOTE 1 (see below)

  const importModule = (modulePath: string) => {
    return lazy(() => import(`./modules/${modulePath}`));
  };

  const loadModules = useCallback(
    async () => {
      const moduleLoadPromises = ['clock/ClockModule'] // <-- NOTE 2 (see below)
        .map(async (modulePath) => {
            const Module = await importModule(modulePath);
            return (<Module key={shortid.generate()}/>);
         });
      
      Promise.all(moduleLoadPromises).then(setModules);
    },[setModules],)

  useEffect(() => {
    
     loadModules();

  },[]);

  return (
    <ToastProvider placement={'top-right'} autodismisstimeout={2000}>
      <React.Suspense fallback='Loading modules...'>
        <Dashboard>
          {modules}
          {/*<WeatherModule/> <-- NOTE 3 (see below) */}
        </Dashboard>
      </React.Suspense>
    </ToastProvider>
  )
}

仪表板.tsx

const Dashboard: FC<IDashboard> = (props) => {

    const dashboardContext = useContext(DashboardContext);
    const [Layout,setLayout] = useState<GridLayout.Layout[]>(dashboardContext.LoadLayout());

    const children = useMemo(() => {

        const gridItems = React.Children.toArray(props.children);
        
        return gridItems.map((val: any,idx) => {
            
            const gridLayout = {
                x: val.props.x,y: val.props.y,w: val.props.w,h: val.props.h,minW: val.props.minW,minH: val.props.minH,maxW: val.props.maxW,maxH: val.props.maxH,};
            
            return <GridItemWrapper editMode={dashboardContext.EditMode} key={`${val.props.i}-${idx}`} data-grid={gridLayout}>{val}</GridItemWrapper>
        });
    },[props.children]);

    const resetGrid = useCallback(
        () => {
            setLayout([]);
        },[setLayout],);


    return(
        <>
            {dashboardContext.EditMode && (
                <EditModeBar onResetGridClick={resetGrid} onSaveClick={saveLayout} />
            )}
            <FullWidthGridLayout  
                cols={12}
                rowHeight={50}
                className='layout'
                compactType={null}
                containerPadding={[15,15]}
                margin={[8,8]}
                maxRows={12}
                layout={Layout}
                isResizable={dashboardContext.EditMode}
                isDraggable={dashboardContext.EditMode}
                preventCollision
                onLayoutChange={onLayoutChange}
                >
                {children}
            </FullWidthGridLayout>
        </>
    )

}

我遇到的问题是,如果我只加载 1 个组件(参见 App.tsx 中的注意 2),如果我将另一个组件添加到列表中,则一切都按预期工作,它会失败并且我从 React Grid Layout 收到错误说:

Uncaught Error: ReactGridLayout: ReactGridLayout.children[0].x must be a number!

还有一点需要注意,如果我不使用组件初始化 modules 状态(请参阅 App.tsx 中的注释 1),那么我也会收到错误

如果我在一个组件中进行硬编码,例如 App.tsx 中的 NOTE 3 被取消注释,那么我可以毫无问题地加载多个组件。

我错过了什么导致这种行为的原因,我怎样才能得到它以便所有模块都导入并且不需要硬编码?

编辑:另外要注意的是,在 Dashboard.tsx 中映射到 <GridItemWrapper /> 时记录 val 时,没有任何预期的道具存在。当组件“正常”使用时(硬编码,如 App.tsx 中的 NOTE 3),它们通常会在那里并通过组件认道具设置。 我怎样才能让延迟加载的组件在它到达映射调用之前实际......加载?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...