这让我难过了几天。在与一位同事讨论了一段时间后,我们决定卸载预先加载所有组件的性能损失所需的工作量不适用于我们的 30-50 个组件的场景。
可以使用延迟加载,但我决定不这样做,因为额外的 10 毫秒加载(如果是这样的话)根本不会引起注意。
import SomeComponent from "./SomeComponent.js"
const spoofedComponents = {
SomeComponent: <SomeComponent />
}
const replaceFunc = (attribs, children) => {
const keys = Object.keys(spoofedComponents);
for(var i in keys) {
const key = keys[i];
// lower case is important here because react converts everything to lower case during text-to-html conversion - only react components can be camel case whereas html is pascal case.
if(attribs.name === key.toLowerCase()) {
return spoofedComponents[key];
}
}
return <p>unknown component</p>
}
...
//inside render
const raw = "<SomeComponent><SomeComponent />"
// it's VERY important that you do NOT use self-closing tags otherwise your renders will be incomplete.
{parse(raw, {
replace: replaceFunc
})}
在我的例子中,我导入了 30 多个组件并映射到我的 spoofedComponents 常量。这有点麻烦,但这是必要的,因为 react 需要了解给定情况的所有信息,以便虚拟 dom 可以做它应该做的事情 - 节省显示性能。优点是,现在非开发人员(编辑)可以使用 WYSIWYG 构建布局,并使用开发人员制作的组件进行显示。
干杯!
编辑
我仍然坚持添加自定义道具和孩子。
编辑
基本道具正在使用
const spoofedComponents = {
SomeComponent: (opts) => {
let s = {};
if(opts.attribs.style)
s = JSON.parse(opts.attribs.style);
if(opts.attribs.classname) {
opts.attribs.className = opts.attribs.classname;
delete opts.attribs.classname;
}
return <APIRequest {...opts.attribs} style={s}>{opts.children[0].data}</APIRequest>
}
}
...
const replaceFunc = (opts) => {
const keys = Object.keys(spoofedComponents);
for(var i in keys) {
const key = keys[i];
if(opts.name === key.toLowerCase()) {
const cmp = spoofedComponents[key](opts);
return cmp;
}
}
return <p>unknown component</p>
}
现在要弄清楚如何动态添加子组件..
编辑
这已经足够好了,我将保持原样。这是更新后的replaceFunc
const replaceFunc = (obj) => {
const keys = Object.keys(spoofedComponents);
for(var i in keys) {
const key = keys[i];
if(obj.name === key.toLowerCase()) {
if(obj.attribs.style)
obj.attribs.style = JSON.parse(obj.attribs.style);
if(obj.attribs.classname) {
obj.attribs.className = obj.attribs.classname;
delete obj.attribs.classname;
}
return React.createElement(spoofedComponents[key], obj.attribs, obj.children[0].data)
}
}
return obj; //<p>unknown component</p>
}