Есть ли способ переместить jsx из функции рендеринга компонента в отдельный файл? Если да, то как я могу ссылаться на jsx в функции рендеринга?
React.js: как отделить jsx от JavaScript
Ответ 1
Вот шаблон для разделения шаблона jsx, который использует модули CommonJS в NodeJS, Browserify или Webpack. В 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.
Обновление 12/2016: актуальная практика заключается в использовании расширения .js и использовании инструмента построения, такого как Babel, для вывода финального javascript из вашего источника. Посмотрите create-react-app, если вы только начинаете. Кроме того, последние рекомендации React рекомендуют разделение между компонентами, которые управляют состоянием (обычно называемыми "компонентами контейнера" ), и компонентами, которые являются презентационными. Эти составные компоненты теперь могут быть записаны как функции, поэтому они не за горами от функции шаблона, использованной в предыдущем примере. Вот как я бы рекомендовал отключить большую часть современного 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>
);
};
Ответ 2
Вы можете использовать react-templates. Это дает вам именно такое разделение между разметкой и самим компонентом и многое другое.
Я нашел его очень полезным для своих нужд (крупномасштабное веб-приложение).
Ответ 3
Одна проблема с перемещением шаблонов в отдельный файл заключается в том, что если вы используете обработчики типа:
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)();
},
Теперь вы можете поместить это определение шаблона куда угодно, в отдельный файл или, тем не менее, хотите структурировать и ссылаться на свой собственный код. (власть вам! Не слушайте эти сумасшедшие предписывающие рамки!:))
Ответ 4
Я просто разделил 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
.
Ответ 5
Если вы не используете какую-либо модульную систему, т.е. полагайтесь только на теги script
, просто выставляйте свой компонент JSX в глобальной переменной и используйте его, когда вам нужно:
// component.js
var Component = React.createClass({ /* your component */ });
// main.js
React.renderComponent(Component({}), domNode);
Примечание. Тег script
для component.js должен появиться перед тегом script
для main.js.
Если вы используете подобную 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);