如何将js组件反应分成多个文件

时间:2016-02-01 10:06:45

标签: javascript reactjs

我正在尝试将每个组件分成单独的文件以获得更好的模块化。虽然我在索引页面上包含了组件jsx文件,但我仍然得到Uncaught ReferenceError: TopicsList is not defined

以下是代码:

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>React.js Demo</title>

    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="css/style.css">

    <script src="//code.jquery.com/jquery-2.2.0.min.js"></script>
    <script src="//fb.me/react-0.14.5.js"></script>
    <script src="//fb.me/react-dom-0.14.5.js"></script>
    <script src="//fb.me/JSXTransformer-0.12.2.js"></script>
    <script src="../components/layout.jsx" type="text/jsx"></script>
    <script src="../components/topic-list.jsx" type="text/jsx"></script>
</head>
<body>
    <div id="main-container"></div>
</body>
</html>

layout.jsx

"use strict";

var Layout = React.createClass({

    render: function() {    
        return (
            <div className="container">
                <TopicsList />

            </div>
        );
    }
});

ReactDOM.render(<Layout />, document.getElementById('main-container'));

主题的list.jsx

"use strict";
var TopicsList = React.createClass({

    getInitialState: function () {
        return {
            isTopicClicked : false,
            topicPages
        };
    },

    onClick: function (topicID) {
        this.setState({isTopicClicked : true});
        this.setState({topicsID : topicID});
    },

    render: function () {
        return (
            <div>
                <div className="row topic-list">
                    <SingleTopicBox 
                        topicID="1" 
                        onClick={this.onClick} 
                        label="Topic"
                        />
                    <SingleTopicBox 
                        topicID="2" 
                        onClick={this.onClick} 
                        label="Topic"
                        />
                    <SingleTopicBox 
                        topicID="3" 
                        onClick={this.onClick} 
                        label="Topic"
                        />
                    <SingleTopicBox 
                        topicID="4" 
                        onClick={this.onClick} 
                        label="Topic"
                        />
                </div>
                <div className="row">
                { this.state.isTopicClicked ? <SelectedTopicPage topicsID={this.state.topicsID} key={this.state.topicsID} topicPages={topicPages} /> : null }
                </div>
            </div>
        );
    }
});


var SingleTopicBox = React.createClass({

    render: function () {
        return (
            <div>
                <div className="col-sm-2">
                    <div onClick={this.props.onClick.bind(null, this.props.topicID)} className="single-topic" data-topic-id={this.props.topicID}>
                        {this.props.label} {this.props.topicID}
                    </div>
                </div>
            </div>
        );
    }
});

var topicPages = [
    { 
        topic_no: '1',
        topic_pages: [
            {
                headline: 'Topic 1 headline', 
                description: 'Topic 1 description comes here...page 1'
            },
            {
                headline: 'Topic 1 headline', 
                description: 'Topic 1 description comes here...page 2'
            },
            {
                headline: 'Topic 1 headline', 
                description: 'Topic 1 description comes here...page 3'
            }
        ]
    },
    { 
        topic_no: '2',
        topic_pages: [
            {
                headline: 'Topic 2 headline', 
                description: 'Topic 2 description comes here...page 1'
            },
            {
                headline: 'Topic 2 headline', 
                description: 'Topic 2 description comes here...page 2'
            },
            {
                headline: 'Topic 2 headline', 
                description: 'Topic 2 description comes here...page 3'
            }
        ]
    },
    { 
        topic_no: '3',
        topic_pages: [
            {
                headline: 'Topic 3 headline', 
                description: 'Topic 3 description comes here...page 1'
            },
            {
                headline: 'Topic 3 headline', 
                description: 'Topic 3 description comes here...page 2'
            },
            {
                headline: 'Topic 3 headline', 
                description: 'Topic 3 description comes here...page 3'
            }
        ]
    },
    { 
        topic_no: '4',
        topic_pages: [
            {
                headline: 'Topic 4 headline', 
                description: 'Topic 4 description comes here...page 1'
            },
            {
                headline: 'Topic 4 headline', 
                description: 'Topic 4 description comes here...page 2'
            },
            {
                headline: 'Topic 4 headline', 
                description: 'Topic 4 description comes here...page 3'
            }
        ]
    },

];

var SelectedTopicPage = React.createClass({
    getInitialState: function() {
      return{
        topicPageNo: 0,
        total_selected_topic_pages: 1
      }
    },
    navigateBack: function() {
        let topicPageNo;
        if (this.state.topicPageNo > 0){
            topicPageNo = this.state.topicPageNo - 1;   
        }
        else {
            topicPageNo = 0;
        }
        this.setState({topicPageNo : topicPageNo});
    },
    navigateNext: function(totalPagesInSelectedTopic) {
        let topicPageNo;
        if (totalPagesInSelectedTopic > this.state.topicPageNo + 1){
            topicPageNo = this.state.topicPageNo + 1;
        }
        else {
            topicPageNo = this.state.topicPageNo;
        }
        this.setState({topicPageNo : topicPageNo});
    },
    render: function() {
        let topicsID = this.props.topicsID;
        let topicPageNo = this.state.topicPageNo;
        return (
            <div>
                {this.props.topicPages.filter(function(topicPage) {
                    // if condition is true, item is not filtered out
                    return topicPage.topic_no === topicsID; 
                }).map(function (topicPage) {
                    let totalPagesInSelectedTopic = topicPage.topic_pages.length;
                    return (
                        <div>
                            <div>
                            <SelectedTopicPageMarkup headline={topicPage.topic_pages[0].headline} key={topicPage.topic_no}>
                                {topicPage.topic_pages[topicPageNo].description}
                            </SelectedTopicPageMarkup> 
                            </div>
                            <div>
                                <NextPrevBtn moveNext={this.navigateNext.bind(this, totalPagesInSelectedTopic)} key={topicPage.topic_no} moveBack={this.navigateBack}/>
                            </div>
                        </div>
                    );
                }.bind(this))}
            </div>
        );
    }
});


var SelectedTopicPageMarkup = React.createClass({

    render: function() {    
        return (
            <div className="topics-page">
                <h1>{this.props.headline}</h1>
                <p>{this.props.children}</p>
            </div>
        );
    }
});


var NextPrevBtn = React.createClass({
    render: function() {    
        return (
            <div className="next-prev-btn">
                <a onClick={this.props.moveBack} className="btn prev-btn">Back</a>
                <a onClick={this.props.moveNext} className="btn next-btn">Next</a>
            </div>
        );
    }
});

1 个答案:

答案 0 :(得分:2)

在您的特定情况下,您应该在layout.jsx之前加载topic-list.jsx 但为了更好的模块化,我建议你尝试使用一些捆绑系统,如webpack或browserify