React.js:如何从JavaScript中分离出jsx
有没有办法将jsx从一个组件的渲染function移动到一个单独的文件? 如果是这样,我怎么在渲染函数中引用jsx?
这里是一个模式,用于分离在NodeJS,Browserify或Webpack中使用CommonJS模块的模板jsx。 在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的答案中纳入了build议,在模板函数中设置React组件。
Update 12/2016:目前的最佳做法是使用.js扩展名,并使用像Babel这样的构build工具来输出源代码中的最终javascript。 看看create-react-app,如果你刚开始。 此外,最新的React最佳实践还build议将pipe理状态的组件(通常称为“容器组件”)和组件表示分离。 这些表示组件现在可以写成函数,所以它们与前面示例中使用的模板函数相差不远。 这里是我build议如何解耦大部分的演示JSX代码。 这些示例仍然使用ES5 React.createClass()
语法 。
// 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> ); };
你可以使用react-templates 。 它给你准确的标记和组件本身之间的分离,等等。
我发现它非常适合我的需求(一个大型的networking应用程序)。
将模板移动到单独的文件中的一个问题是,如果使用如下处理程序:
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)(); },
现在,您可以将该模板定义放置在单独的文件中,或者您想要构build和引用自己的代码。 (权力给你!不要听这些疯狂的说明性框架:))
我只是将JSX分成匿名函数文件
template.js
export default (component) => { return <h1>Hello {component.props.name}</h1> }
我-component.js
import React, {Component} from 'react'; import template from './template'; export default MyComponent extends Component { render() { return template(this); } }
在模板中,您可以使用component
variables访问道具或状态或function。
如果您不使用任何模块系统,即仅依赖script
标记,那么可以简单地将JSX组件暴露在全局variables中,并在需要时使用它:
// component.js var Component = React.createClass({ /* your component */ }); // main.js React.renderComponent(Component({}), domNode);
注意: component.js的script
标签必须出现在main.js的script
标签之前。
如果您使用像Browserify这样的Commonjs模块系统,只需导出您的组件定义并在需要时input。
// component.js var React = require("react"); module.exports = React.createClass({ /* your component */ }); // main.js var Component = require("component.js"); React.renderComponent(Component({}), domNode);