渲染多个组件

时间:2016-03-19 14:57:59

标签: reactjs

我对React很新,可能会有点过分。

在我的应用中,我尝试制作文档构建器(有点像在mailchimp中构建电子邮件)。单击元素图标时,该元素的标记将添加到文档页面。

从概念上讲,我不确定在React中执行此操作的最佳方法。我的问题包括:

  • 如何跟踪哪些元素已添加到文档中?
  • 我是否在应用级别管理状态?
  • 最后,我希望用户自定义添加到文档中的每个元素的样式,代码应该放在哪里?
  • 似乎数据和功能的顺序很重要(有时它会在此顺序发生变化时中断)。有没有更好的方法来组织这个?

目前,任何关于“反应”的建议都是'如此设置的方式将不胜感激。

我的主要JS:

// ---------------------------------------------------------
// Elements
// ---------------------------------------------------------
var TextBlock = React.createClass({
    render: function() {
        return (
            <p>Lorem ipsum ... laborum.</p>
        );
    }
});

var ImageBlock = React.createClass({
    render: function() {
        return (
            <img src="placehold.it/360x240" alt="Image" />
        );
    }
});

var HeadingBlock = React.createClass({
    render: function() {
        return (
            <h3>Heading Here</h3>
        );
    }
});

var TableBlock = React.createClass({
    render: function() {
        return (
            <table>
                ... Table Markup Here ...
            </table>
        );
    }
});

var ColumnsBlock = React.createClass({
    render: function() {
        return (
            <div class="row">
                <div class="col-xs-4">Col 1</div>
                <div class="col-xs-4">Col 2</div>
                <div class="col-xs-4">Col 3</div>
            </div>
        );
    }
});

var Divider = React.createClass({
    render: function() {
        return (
            <hr />
        );
    }
});

var elementList = [
    {
        'name': 'Text',
        'icon': 'align-left',
        'html': <TextBlock />
    },
    {
        'name': 'Image',
        'icon': 'picture-o',
        'html': <ImageBlock />
    },
    {
        'name': 'Heading',
        'icon': 'header',
        'html': <HeadingBlock />
    },
    {
        'name': 'Table',
        'icon': 'table',
        'html': <TableBlock />
    },
    {
        'name': 'Column',
        'icon': 'columns',
        'html': <ColumnsBlock />
    },
    {
        'name': 'Divider',
        'icon': 'times',
        'html': <Divider />
    },
];

var Element = React.createClass({
    handleClick: function(e){
        e.preventDefault();
        this.props.handleClick();
    },

    render: function() {
        return (
            <li className="element" onClick={this.handleClick}>
                <i className={'fa fa-' + this.props.icon}></i>
                <span className="element__name">{this.props.name}</span>
            </li>
        );
    }
});

var Elements = React.createClass({
    getInitialState: function () {
        return {
            elementList: elementList,
        };
    },

    handleClick: function(index, element){
        console.log(element.html);
    },

    render: function() {
        return (
            <ul className="list-unstyled">
                {this.state.elementList.map(function(element, index) {
                    return (
                        <Element
                            key={index}
                            handleClick={this.handleClick.bind(this, index, element)}
                            name={element.name}
                            icon={element.icon}
                        />
                    );
                }.bind(this))}
            </ul>
        );
    }
});

// ---------------------------------------------------------
// Tabs
// ---------------------------------------------------------

var Tab = React.createClass({
    handleClick: function(e){
        e.preventDefault();
        this.props.handleClick();
    },

    render: function() {
        return (
            <a className={this.props.isCurrent ? 'btn btn-primary' : 'btn btn-default'} onClick={this.handleClick}>
                {this.props.name}
            </a>
        );
    }
});

var Tabs = React.createClass({
    handleClick: function(tab){
        this.props.changeTab(tab);
    },

    render: function(){
        return (
            <div className="text-center">
                <nav className="btn-group">
                    {this.props.tabList.map(function(tab, index) {
                        return (
                            <Tab
                                key={index}
                                handleClick={this.handleClick.bind(this, index)}
                                name={tab.name}
                                isCurrent={(this.props.currentTab === index)}
                             />
                        );
                    }.bind(this))}
                </nav>
            </div>
        );
    }
});

var Settings = React.createClass({
    render: function() {
        return (
            <div>test settings</div>
        );
    }
});

var tabList = [
    {
        'name': 'Content',
        'content': <Elements />
    },
    {
        'name': 'Settings',
        'content': <Settings />
    }
];

var Document = React.createClass({
    render: function() {
        return (
            <article className="document__frame">
                <div className="document">test</div>
            </article>
        );
    }
});

var App = React.createClass({
    getInitialState: function () {
        return {
            tabList: tabList,
            currentTab: 0
        };
    },

    changeTab: function(index) {
        this.setState({ currentTab: index });
    },

    render: function() {
        return (
            <div>
                <Document />
                <div className="control">
                    <Tabs
                        currentTab={this.state.currentTab}
                        tabList={this.state.tabList}
                        changeTab={this.changeTab}
                    />
                    <div className="control__panel">
                        {this.state.tabList[this.state.currentTab].content}
                    </div>
                </div>
            </div>
        );
    }
});

ReactDOM.render(
    <App />,
    document.getElementById('content')
);

1 个答案:

答案 0 :(得分:1)

反应方式是使用处理所有状态更改的容器组件。

此外,每个组件都有一个生命周期和生命周期方法,可用于更改状态

您的问题:

  • 如何跟踪哪些元素已添加到文档中?

可以使用componentDidMount()

完成此操作
  • 我是否在应用级别管理状态?

  • 最终,我希望用户自定义每个元素的样式 添加到文档中,该代码应该在哪里生效?

由您决定,您可以编写内联样式&#39;或要求/导入来自不同文件的样式

  • 看起来数据和功能的顺序很重要(有时它 这个订单改变时中断)。有没有更好的组织方式 此?

是的,见下文

关于容器:

https://medium.com/@learnreact/container-components-c0e67432e005#.igjce0wof

以下是有关生命周期的React文档中的相关链接:

https://facebook.github.io/react/docs/component-specs.html#lifecycle-methods