渲染多个React组件的最佳方法是什么

时间:2018-04-17 16:29:48

标签: reactjs redux

我想创建一个以下的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>

也许有任何模式,良好做法或工具可以存档。

2 个答案:

答案 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 />;
}

codesandbox for demo

编辑: 将所有映射到组件放在单独文件中的原因是要分离关注点。使用传统的switchif逻辑将要求您在App容器中添加至少2行代码。随着时间的推移,您的App容器可能会非常冗长。如果您的App容器也处理其他事情(不仅仅是映射到组件),那么使用它也不是很愉快。

通过使用单独的文件,您的App容器将不会填充所有关注的映射。单独的文件也比使用switchif更简洁。比较添加

'KEY': ComponentX,

case 'KEY': ComponentX; break;

最后但并非最不重要的是,使用switchif将导致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);