动态加载状态内的反应组分

时间:2017-12-14 10:35:53

标签: javascript reactjs asynchronous

我手边有一个非常有趣的问题。

我目前正在为无头CMS开发管理界面,我想动态加载组件以查看不同部分的内容。

我知道从v4开始就很容易实现React Router,但我不想依赖Routes来处理这个问题以保持URL尽可能干净。

以下是我要做的事情:

  1. 我想渲染UI的基本布局(我在其中加载了 单击导航链接时的不同子组件
  2. 在此基本布局的async componentWillMount()函数内,我想使用import()
  3. await import()表示组件
  4. 理想情况下,这些应存储在名为this.state.mainComponents
  5. 的属性中的状态
  6. 然后,我会将组件的名称传递给导航组件以及一个将更改父项state中当前显示的组件的函数
  7. 我尝试了几种不同的方法,但直到现在才设法让它工作。

    这就是我现在所拥有的:

      async componentDidMount() {
        const mainComponents = {
          Dashboard: await import('../_mainComponents/Dashboard').then(
            ({ Dashboard }) => {
              return Dashboard;
            },
          ),
        };
    
        const componentNames = [];
    
        for (let p in mainComponents) {
          componentNames.push(p);
        }
    
        this.setState({
          mainComponents: {
            views: mainComponents,
            names: componentNames,
          },
          currentComponent: mainComponents.Dashboard,
          currentTitle: 'Dashboard',
        });
      }
    

    我真的很感激你能给我的任何帮助。

    编辑:

    所以根据@MosèRaguzzini的回答,我再次实现了react-loadable并尝试将const存储在我的状态中:

    const LoadableDashboard = Loadable({
      loader: () => import('../_mainComponents/Dashboard'),
      loading: Loading
    });
    
    const mainComponents = {
      Dashboard: LoadableDashboard
    };
    

    在我的构造函数中,我试图将此Object传递到这样的状态:

    const componentNames = [];
    
    for (let p in mainComponents) {
      componentNames.push(p);
    }
    
    this.state = {
      mainComponents: {
        views: mainComponents,
        names: componentNames,
      },
      currentComponent: null,
      currentTitle: null,
      loading: false,
    };
    

    尝试将存储在this.state.mainComponents.views对象内部的组件输出到渲染函数时,它不起作用。

    当使用<Dashboard />时它正在按预期工作,但这不是我想在这里完成的,因为我不想在大量switch ... case中将每个组件添加到渲染函数中。

    你们中有谁知道如何才能做到这一点?

2 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法,并希望与所有在我寻找合适答案之后的人分享。

这是我做的:

import Loadable from 'react-loadable';
import Loading from '../_helperComponents/Loading';

// Define the async-loadable components here and store them inside of the mainComponent object
const LoadableDashboard = Loadable({
  loader: () => import('../_mainComponents/Dashboard'),
  loading: Loading,
});

const LoadableUserOverview = Loadable({
  loader: () => import('../_mainComponents/UserOverview'),
  loading: Loading,
});

const mainComponents = {
  Dashboard: <LoadableDashboard />,
  User: <LoadableUserOverview />,
};

我不会将组件存储在我的状态中(这可能会违反指导原则,因为我通过进一步研究状态发现了这一点):D

使用此对象,我可以通过在render()函数中输出相应的组件来调用相应的组件,如下所示:

render() {
  return (
    <div>
      {mainComponents[this.state.currentComponent]}
    </div>
  );
}

我希望我可以帮助这个人。 快乐的编码!

答案 1 :(得分:0)

我建议看一下反应可加载:

import Loadable from 'react-loadable';
import Loading from './my-loading-component';

const LoadableComponent = Loadable({
  loader: () => import('./my-component'),
  loading: Loading,
});

export default class App extends React.Component {
  render() {
    return <LoadableComponent/>;
  }
}

它以干净的风格提供您所需的功能。