我正在与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播放器和照片组件也会加载——只是没有使用。
所以。。。有没有一种方法可以基于数据来呈现组件,从而导致正确的代码分割?
非常感谢!
我正在考虑另一种方法;在一个基于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
中导入(并渲染为<Switcher/>
将获得一个组件并完成任务。
如果问题坏了,我很乐意上传,但我希望你能得到我的解决办法。
让我知道它是如何工作的!
React Loadable对我来说非常出色。这就是添加库使捆绑包变小的情况之一。
您可能还想将异步加载推迟到用户滚动到特定元素时,而这个库本身并不能做到这一点。您可以轻松地将原始版本与InteractionObserver版本混合使用-react可加载可见性。然而,请确保你有一个很好的方法来处理CLS(累积布局偏移(,否则Lighthouse会抱怨你的网站元素让你的用户感到沮丧。