我想创建一个以下的React / Redux应用程序,我正在寻找最佳方法来处理这个问题。
让我们从主App
容器开始:
class App extends React.Component {
render() {
const {open} = this.props;
return open ? <Maximized/> : <Minimized/>;
}
}
const mapStateToProps = (state) => ({
open: getIsOpen(state)
});
export default connect(
mapStateToProps,
{}
)(App);
现在它很简单 - 取决于我只渲染两个容器的状态。 Minimized
容器很容易让我们跳过它。
在Maximized
容器中,我想显示不同的视图(?)。
class Maximized extends React.Component {
render() {
const {view} = this.props;
let content = null;
if (view === 'DEFAULT') {
content = <Component1/>
} else if (view === 'COMPONENT2') {
content = <Component2/>
}
return <div>
{content}
<Close/>
</div>;
};
}
const mapStateToProps = (state) => ({
view: getView(state)
});
export default connect(
mapStateToProps,
{}
)(Maximized);
view
来自状态选择器getView
,由简单的if处理,但现在我只有两个组件要显示,将来我认为这些组件可以 n
我认为路由器有MemoryRouter(我不能使用URL),但我不知道这是一个好方法,因为我必须将当前状态存储在本地存储中。 / p>
也许有任何模式,良好做法或工具可以存档。
答案 0 :(得分:1)
嗯,有这么多组件使用相同的URL有点奇怪。话虽如此,如果你绝对不能使用URL,我想你可以创建一个导入所有组件的文件,并导出一个作为view
值和组件类之间的映射的对象。类似的东西:
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
import ComponentC from './ComponentC';
export default {
'DEFAULT': ComponentA,
'PROFILE': ComponentB,
'CONTACT': ComponentC,
}
然后在你的App
容器中,你可以做这样的事情:
import ComponentMap from './ComponentMap';
...
...
...
render() {
const Component = ComponentMap[this.state.view];
return <Component />;
}
编辑:
将所有映射到组件放在单独文件中的原因是要分离关注点。使用传统的switch
或if
逻辑将要求您在App容器中添加至少2行代码。随着时间的推移,您的App容器可能会非常冗长。如果您的App容器也处理其他事情(不仅仅是映射到组件),那么使用它也不是很愉快。
通过使用单独的文件,您的App容器将不会填充所有关注的映射。单独的文件也比使用switch
或if
更简洁。比较添加
'KEY': ComponentX,
到
case 'KEY': ComponentX; break;
最后但并非最不重要的是,使用switch
或if
将导致O(n)时间来获取您正在寻找的组件,相比之下,如果您使用的是javascript对象则为O(1)时间
答案 1 :(得分:1)
我经常使用类似的模式,我觉得它运作良好。一个变化是我会稍微清理你的条件逻辑。我会使用switch
代替,以便处理 n 数量的组件更加轻松和清晰:
class Maximized extends React.Component {
getView = () => {
const {view} = this.props;
switch(view) {
case 'DEFAULT': {
return <Component1/>
}
case 'COMPONENT2': {
return <Component2/>
}
case 'COMPONENT3': {
return <Component3/>
}
default: {
return <Component1 />
}
}
};
render() {
const content = this.getView();
return <div>
{content}
<Close/>
</div>;
};
}
const mapStateToProps = (state) => ({
view: getView(state)
});
export default connect(
mapStateToProps,
{}
)(Maximized);