Javascript 将 React 类移动到单独的文件中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32301490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:51:47  来源:igfitidea点击:

Moving React classes into separate files

javascriptreactjs

提问by SeanPlusPlus

After doing the React tutorialthis is my index.html file:

完成React 教程后,这是我的 index.html 文件:

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script src="lib/main.js"></script>
  </body>
</html>

And this is my src/main.jsx file:

这是我的 src/main.jsx 文件:

var CommentBox = React.createClass({
  getInitialState: function() {
    return {data: []};
  },
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});

    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments Yo</h1>
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
        <CommentList data={this.state.data} />
      </div>
    );
  }
});

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }

    // send request to the server
    this.props.onCommentSubmit({author: author, text: text});
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
    return;
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function (comment) {
      return (
        <Comment author={comment.author}>
          {comment.text}
        </Comment>
      );
    });
    commentNodes.reverse();
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

var Comment = React.createClass({
  render: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
        <hr />
      </div>
    );
  }
});

React.render(
  <CommentBox url="comments.json" pollInterval={2000} />,
  document.getElementById('content')
);

Additionally, I am running this command to turn my jsx into js:

此外,我正在运行此命令将我的 jsx 转换为 js:

babel --watch src/ --out-dir lib/

I would like to move each React class into its own file. For example, I would like to create the following four files (note: each map to a top level "var" declaration in my main.jsx file) and pull all of these classes into my main.jsx file:

我想将每个 React 类移动到它自己的文件中。例如,我想创建以下四个文件(注意:每个文件都映射到我的 main.jsx 文件中的顶级“var”声明)并将所有这些类拉入我的 main.jsx 文件:

comment.jsx
commentList.jsx
commentForm.jsx
commentBox.jsx

How do I do this?

我该怎么做呢?

After banging my head on require and es6 for a while here, I still do not have a good intuition of how to separate all these apart, or if something like require / es6 is even the right way to approach this.

在这里我对 require 和 es6 敲了一阵子之后,我仍然没有很好的直觉来了解如何将所有这些分开,或者像 require / es6 这样的东西是否甚至是解决这个问题的正确方法。

Thanks for the help!

谢谢您的帮助!

回答by Hemaolle

In a project created with the create-react-apptool separating components seems to work fine like this. Define the component in a file Hello.jsx:

在使用create-react-app工具分离组件创建的项目中,似乎可以像这样正常工作。在文件中定义组件Hello.jsx

import React from 'react';

var Hello = React.createClass({
  render: function() {
    return (
      <p>Hello world!</p>
    );
  }
});

// Must export!
export default Hello;

And then you can import the component in another file with

然后你可以在另一个文件中导入组件

import Hello from './Hello.jsx'

回答by dreyescat

If you want to create a file for each React class, I would recommend to take a look at webpack. You can develop your React classes as CommonJs modules and it will take care of bundling them together.

如果您想为每个 React 类创建一个文件,我建议您查看webpack。您可以将 React 类开发为 CommonJs 模块,它会负责将它们捆绑在一起。

Also, I think it is a good option because you want to use babelto transform your jsxfiles. This is solved with webpack loaders.

另外,我认为这是一个不错的选择,因为您想使用babel来转换您的jsx文件。这可以通过webpack loaders解决。

The basic webpack configuration file would contain something like this:

基本的 webpack 配置文件将包含如下内容:

webpack.config.js

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: './src/main.jsx',
  output: {
    // Output the bundled file.
    path: './lib',
    // Use the name specified in the entry key as name for the bundle file.
    filename: 'main.js'
  },
  module: {
    loaders: [
      {
        // Test for js or jsx files.
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel'
      }
    ]
  },
  externals: {
    // Don't bundle the 'react' npm package with the component.
    'react': 'React' 
  },
  resolve: {
    // Include empty string '' to resolve files by their explicit extension
    // (e.g. require('./somefile.ext')).
    // Include '.js', '.jsx' to resolve files by these implicit extensions
    // (e.g. require('underscore')).
    extensions: ['', '.js', '.jsx']
  }
};

I created a GitHub react-tutorial-webpackrepository if you want to have actual code.

如果您想拥有实际代码,我创建了一个 GitHub react-tutorial-webpack存储库。

回答by Fran?ois Richard

In my opinion ES6 can be a way to write classes and module but not really to manage them. For the purpose of managing modules I would use requirejs, simplest module manager that I know. But maybe other people will advise something else.

在我看来,ES6 可以是一种编写类和模块的方式,但不是真正管理它们的方式。为了管理模块,我将使用 requirejs,这是我所知道的最简单的模块管理器。但也许其他人会提出其他建议。

IMO you need a module manager and requirejs is a great tool for that.

IMO 你需要一个模块管理器,而 requirejs 是一个很好的工具。

Update: Basically for requirejs you'll write a main.js file (which is a conf file for require, defining the paths of modules and first thigns to load) In your main html you'll write something like this to load the main.js

更新:基本上对于requirejs,您将编写一个main.js 文件(这是一个用于require 的conf 文件,定义模块的路径和要加载的第一个thigns)在您的主html 中,您将编写类似这样的内容来加载main。 js

<script data-main="scripts/main" src="scripts/require.js"></script>

Inside your views you'll call the module you need using define('MyModule'...) using the name you previously defined in the main.js (with the path).

在您的视图中,您将使用之前在 main.js 中定义的名称(带有路径)使用 define('MyModule'...) 调用您需要的模块。

Read the doc,don't worry this is not that terrible: http://requirejs.org/docs/start.html#addHere is a simple example: https://github.com/volojs/create-template

阅读文档,不要担心这不是那么糟糕:http: //requirejs.org/docs/start.html#add这是一个简单的例子https: //github.com/volojs/create-template

The way to break your code is pretty easy you'll return (this how you export a module with define()) your reactclass. Create one file for each class you have. But you can also create module/utils to gather transverse functions (parsing...etc).

破坏代码的方法非常简单,您将返回(这是您使用define() 导出模块的方式)您的reactclass。 为您拥有的每个班级创建一个文件。但是您也可以创建模块/实用程序来收集横向功能(解析...等)。

Hope it helps!

希望能帮助到你!