【问题标题】:React.js: how to decouple jsx out of JavaScriptReact.js:如何将 jsx 与 JavaScript 分离
【发布时间】:2014-01-11 19:02:42
【问题描述】:

有没有办法将 jsx 从组件的渲染函数移动到单独的文件中?如果是这样,如何在渲染函数中引用 jsx?

【问题讨论】:

  • 你使用browserify吗?然后你可以在文件中写'exports =
    '
  • 我喜欢将模板(jsx)与视图(js)分开
  • 我使用 Eclipse,所以如果我将 jsx 标记混合到我的代码中,我的编辑器将无法工作。此外,我不想仅仅因为这恰好是推荐的方法而将标记混合到我的代码中。在我看来,它仍然很疯狂。无论如何,这是一个完全有效的问题,React 文档总是说将 jsx 放入你的代码中是可选的,所以问“你为什么要这样做?”似乎没有帮助。
  • 见上文。此外,这可以防止开发人员在 jsx 中到处乱扔“this.foo()”。只需在 componentWillUpdate 中将所有字段添加到 state 中,然后在 render 中返回 'myJSX(this.props, this.state)'
  • @sarink 为什么它会破坏整个概念?当你有一个 IDE 可以很容易地快速写出 HTML 时,你必须放弃所有这些才能把它全部写在一个文件中——这很烦人。

标签: javascript reactjs react-jsx


【解决方案1】:

您可以使用react-templates。它为您提供了标记和组件本身之间的准确分离,等等。

我发现它对我的需求非常有用(大型网络应用程序)。

【讨论】:

  • 正是这个。 React 模板还提供了很多有用的功能,例如 ifs repeats 和其他杂项。
【解决方案2】:

将模板移动到单独的文件中的一个问题是,如果您使用以下处理程序:

var myTemplate = (
    <form onSubmit={this.handleSubmit}></form>
);

然后在您使用的组件中:

render: function() {
    return myTemplate;
}

生成的模板代码将调用 this.handleSubmit(),因此“this”将是错误的,处理程序将无法工作。您需要做的就是将它们放入一个函数中,如下所示:

var myTemplate = function() {
    return (
        <form onSubmit={this.handleSubmit}></form>
    );
};

然后在你的组件的渲染函数中,你需要将它正确绑定到'this',然后调用它,像这样:

render: function() {
    return myTemplate.bind(this)();
},

现在您可以将该模板定义放在任何地方、一个单独的文件中,或者您想要构建和引用您自己的代码。 (给你力量!不要听这些疯狂的规定框架!:))

【讨论】:

  • 好提示;一个建议:你可以直接调用myTemplate.call(this)(不需要bind(),它会创建一个新函数)。
【解决方案3】:

这是一种用于分离模板 jsx 的模式,它使用 NodeJS、Browserify 或 Webpack 中的 CommonJS 模块。在 NodeJS 中,我发现 node-jsx 模块有助于避免编译 JSX。

// index.js
require('node-jsx').install({extension: '.jsx'});
var React = require('react'),
    Component = require('./your-component');


// your-component.jsx
var YourComponent,
    React = require('react'),
    template = require('./templates/your-component.jsx');

module.exports = YourComponent = React.createClass({
  render: function() {
    return template.call(this);
  }
});


// templates/your-component.jsx
/** @jsx React.DOM */
var React = require('react');

module.exports = function() {

  return (
    <div>
      Your template content.
    </div>
  );

};

2015 年 1 月 30 日更新:在 Damon Smith 的回答中纳入了将模板函数中的 this 设置为 React 组件的建议。

2016 年 12 月更新:当前的最佳做法是使用 .js 扩展名并使用 Babel 等构建工具从您的源代码中输出最终的 javascript。如果您刚刚开始,请查看create-react-app。此外,最新的 React 最佳实践确实建议将管理状态的组件(通常称为“容器组件”)和展示性组件分开。这些表示组件现在可以编写为函数,因此它们与前面示例中使用的模板函数相差不远。以下是我现在建议解耦大部分演示 JSX 代码的方法。这些示例仍然使用ES5 React.createClass() syntax

// index.js
var React = require('react'),
    ReactDOM = require('react-dom'),
    YourComponent = require('./your-component');

ReactDOM.render(
  React.createElement(YourComponent, {}, null),
  document.getElementById('root')
);

// your-component.js
var React = require('react'),
    YourComponentTemplate = require('./templates/your-component');

var YourComponentContainer = React.createClass({
  getInitialState: function() {
    return {
      color: 'green'
    };
  },

  toggleColor: function() {
    this.setState({
      color: this.state.color === 'green' ? 'blue' : 'green'
    });
  },

  render: function() {
    var componentProps = {
      color: this.state.color,
      onClick: this.toggleColor
    };
    return <YourComponentTemplate {...componentProps} />;
  }
});

module.exports = YourComponentContainer;

// templates/your-component.js
var React = require('react');

module.exports = function YourComponentTemplate(props) {
  return (
    <div style={{color: props.color}} onClick={props.onClick}>
      Your template content.
    </div>
  );
};

【讨论】:

  • 如果您在模板中使用其他组件,则此方法不起作用
  • 我认为您的模板应该能够要求其他组件。没有?
  • @Shivam 如果您的模板函数不需要访问this.propsthis.state,它将起作用。我刚刚用另一个示例更新了答案,该示例显示了 React 中当前的最佳实践,用于将组件分离为用于表示模板和管理状态的容器组件的纯功能组件。
【解决方案4】:

我只是将 JSX 分离成匿名函数文件

template.js

export default (component) => {
return <h1>Hello {component.props.name}</h1>
}

my-component.js

import React, {Component} from 'react';
import template from './template';

export default MyComponent extends Component {
   render() {
     return template(this);
   }
}

在模板中,您可以使用component 变量访问道具或状态或函数。

【讨论】:

  • css加载器、图片加载器等呢?
【解决方案5】:

如果您不使用任何模块系统,即仅依赖script 标签,只需将您的 JSX 组件暴露在全局变量中并在需要时使用它:

// component.js
var Component = React.createClass({ /* your component */ });
// main.js
React.renderComponent(Component({}), domNode);

注意:component.jsscript 标记必须出现在 main.js 的 script 标记之前。

如果您使用类似 Commonjs 的模块系统,例如 Browserify,只需导出您的组件定义并在需要时使用它。

// component.js
var React = require("react");
module.exports = React.createClass({ /* your component */ });
// main.js
var Component = require("component.js");
React.renderComponent(Component({}), domNode);

【讨论】:

    猜你喜欢
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 2016-12-25
    相关资源
    最近更新 更多