【问题标题】:How to render components dynamically in Gatsby.js and use code-splitting?如何在 Gatsby.js 中动态渲染组件并使用代码拆分?
【发布时间】:2020-07-08 15:21:48
【问题描述】:

我正在使用 Gatsby 和 Contentful 构建网站,到目前为止效果很好。我的问题是,我不知道如何根据 Contentful 中的数据动态呈现组件。

假设有一个页面内容类型,它作为组件的标题、url 和字段。这些组件可以是 YouTube 播放器、降价文本或照片。目前我正在使用一个自定义组件,它导入所有可用的组件,然后使用 switch 呈现页面的组件。

switch (contentType) {
  case 'billboard':
    return <Billboard key={key} id={key} {...section.fields}/>;
  case 'photos':
    return <Photos key={key} id={key} {...section.fields}/>;
  case 'postGrid':
    return <PostGrid key={key} id={key} {...section.fields}/>;
  case 'splitView':
    return <SplitView key={key} id={key} {...section.fields}/>;
  case 'text':
    return <Text key={key} id={key} {...section.fields}/>;
  case 'tile':
    return <Tile key={key} id={key} {...section.fields}/>;
  default:
    return null;
}

这样做的问题是 Gatsby 会将所有可用的组件包含在 webpack 块中,如果有很多组件会导致站点崩溃。假设有一个只有文本的页面(例如印记),YouTube 播放器和照片组件也会被加载 - 只是没有使用。

那么...有没有一种方法可以根据数据渲染组件,从而导致正确的代码拆分?

非常感谢!

【问题讨论】:

    标签: reactjs gatsby contentful code-splitting jamstack


    【解决方案1】:

    我正在考虑另一种方法;在基于contentType 呈现您的组件类型的映射组件中,更加简洁,尤其是巨大的性能提升(无需每次都强制代码检查switch 语句)。

    如果没有看到其余代码,很难猜出您是如何打印switch 的。但是,假设您将所有数据都保存在 data 对象中,那么:

    import SwitchComponents from '../../SwitchComponents/SwitchComponents'
    
     // other code
    
      return data.map(item => {
        const Switcher = SwitchComponents[item.contentType];
        return (
          <Switcher
            key={item.key} // or something unique
            {...section.fields}
          />
        );
      })
    

    这个组件应该有类似的结构,例如:

    import Billboard from './Billboard/Billboard';
    import Photos from './Photos/Photos';
    import PostGrid from './PostGrid/PostGrid';
    import SplitView from './SplitView /SplitView';
    import Text from './Text/Text';
    import Tile from './Tile/Tile';
    
    const SwitchComponents= {
      billboard : Billboard,
      photos : Photos,
      postGrid : PostGrid,
      splitView : SplitView,
      text : Text,
      tile : Tile  
    };
    
    export default SwitchComponents
    

    基本上,您用SwitchComponents[item.contentType] 告诉SwitchComponents 的位置应该采取,因为它被映射为一个组件(在SwitchComponents 中导入)并呈现为&lt;Switcher/&gt; 将获得一个组件并且会成功。

    如果问题中断,我很乐意上传问题,但我希望你能得到我的解决方法。

    让我知道它是如何工作的!

    【讨论】:

    • 我知道你要去哪里!我会尝试这种方法,如果它有效,我一定会让你知道! :-)
    【解决方案2】:

    React Loadable 为我工作得非常出色。这是添加库使包更小的情况之一。

    您可能还希望将异步加载推迟到用户滚动到特定元素时,这个库本身不会这样做。您可以轻松地将原始版本与 InteractionObserver 版本 - react-loadable-visibility 混合使用。但是,请确保您有处理 CLS(累积布局转换)的好方法,否则 Lighthouse 会抱怨您的网站元素让您的用户感到沮丧。

    【讨论】:

    • 这似乎不适用于动态加载。您仍然需要对“可加载”组件进行硬编码。所以它有一点帮助,但不能解决这个实际问题
    猜你喜欢
    • 2016-02-24
    • 1970-01-01
    • 2019-12-26
    • 2015-09-07
    • 2021-04-15
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多