有点难以找到关于这种特定模式的任何内容,而且我甚至不确定如何用搜索术语来描述它,所以如果这是一个重复的问题而道歉(尽管我不是认为是)。
我想根据传递给应用程序的订单输出React布局,用户可以通过设置面板进行设置。我的想法是在页面上输出一些不同的容器,我希望用户能够重新安排。请注意,在应用呈现后,此订单不会更改,这一点非常重要。 (我希望用户能够说出"按顺序显示PanelA,PanelC和PanelB")
现在,我已经弄清楚如何使用以下模式来实现这一目标:
// user-ordered array is passed to the app:
const settings = {
layout: [
"panela",
"panelb",
"panelc"
]
}
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
// some state
}
}
renderComponentsInOrder() {
return settings.layout.map(component => {
switch(component) {
case "panela":
return
<PanelA {.../* some state */} />
case "panelb":
return
<PanelB {.../* some state */} />
case "panelc":
return
<PanelC {.../* some state */} />
default: return null
}
})
}
render() {
return this.renderComponentsInOrder()
}
}
&#13;
但这让我感到非常低效。每次渲染运行时都不需要重新计算组件的顺序,因为在应用程序运行时顺序不会发生变化。我已经尝试过像memoizing renderComponentsInOrder方法来缓存计算出的布局或重命名settings.layout数组中的值并直接调用它们,但是由于组件需要,我们无法使用任何东西。根据州进行更新。
非常感谢任何帮助或建议。谢谢!
编辑:理想情况下,我正在寻找基于JS的解决方案,因为兼容性是一个问题,我不想完全依赖浏览器的CSS实现。
答案 0 :(得分:5)
对布兰登给出的答案略有不同。你可以有一个函数来根据state / props生成组件:
const settings = {
layout: [
"panela",
"panelb",
"panelc"
]
};
const panels = settings.layout.map(c => {
switch (c) {
case "panela": return (props, state) => <PanelA key="a" foo={state.foo} />
case "panelb": return (props, state) => <PanelB key="b" bar={state.bar} />
}
});
// Now use panels array to render:
class MyComponent extends React.Component {
render() {
const props = this.props;
const state = this.state;
const ordered = panels.map(p => p(props, state));
return <div>{ordered}</div>
}
}
答案 1 :(得分:2)
方法1:
在呈现之前,只需将settings数组转换为一个Components数组:
const settings = {
layout: [
"panela",
"panelb",
"panelc"
]
};
const panels = settings.layout.map(c => {
switch (c) {
case "panela": return { Component: PanelA, key: c };
case "panelb": return { Component: PanelA, key: c };
...
}
});
// Now use panels array to render:
class MyComponent extends React.Component {
// ...
renderComponentsInOrder() {
return panels.map(({Component, key}) => (
<Component key={key} {.../* some state*/} />
));
}
// ...
}
方法2:
只需创建一个映射表:
const settings = {
layout: [
"panela",
"panelb",
"panelc"
]
};
const panelLookup = {
"panela": PanelA,
"panelb": PanelB,
...
};
// Now use lookup to render:
// Now use panels array to render:
class MyComponent extends React.Component {
// ...
renderComponentsInOrder() {
return settings.layout.map(key => {
const Component = panelLookup[key];
return <Component key={key} {.../* some state*/} />;
});
}
// ...
}