Общая структура при использовании React.js
Глядя на Virtual DOM в React.js, и, проведя несколько тестов производительности, меня очень интересует эта библиотека. Это похоже на идеальное дополнение к Backbone удивительной модели, маршрутизатору и структуре коллекции.
Однако из-за отсутствия качественных обучающих программ и курсов, у меня осталось несколько вопросов, я надеюсь, что кто-то здесь сможет ответить:
Шаблоны HTML
Неужели React полностью устраняет понятие HTML-шаблонов? Я говорю о разметке вашего разметки в отдельном файле HTML (или на той же странице в теге <script type=text/template>
). Вы знаете, как вы делаете с underscore.js Handlebars и т.д.
Примеры Starter kit, похоже, имеют функции JSX или React.DOM
прямо в ваших классах представлений, что кажется мне немного грязным, и я вижу это становится немного из-под контроля, так как ваши взгляды растут по сложности.
Здесь пример, который отображает 2 значения и их сумму, используя базовый элемент Twitter Bootstrap с вложенной таблицей.
var CustomView = React.createClass({
render: function() {
var x = this.props.x;
var y = this.props.y;
return (
<div className="panel panel-primary">
<div className="panel-heading">
<h1 className="panel-title">Should I put all this markup somewhere else?</h1>
</div>
<div className="panel-body">
<table className="table">
<thead>
<tr>
<th>X</th>
<th>Y</th>
<th>Combined val</th>
</tr>
</thead>
<tbody>
<tr>
<td>{x}</td>
<td>{y}</td>
<td>{x + y}</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
});
Мне не интересно знать, возможно ли или нет переместить этот материал в отдельный файл, скорее, я пытаюсь понять, что считается лучшей практикой при работе с React.
Обновление и настройка данных
На странице Why React указано следующее:
Просто сообщите, как ваше приложение должно смотреть на любой данный момент времени, а React автоматически будет управлять всеми обновлениями пользовательского интерфейса при изменении ваших базовых данных.
Я не совсем понимаю, как это работает. Например, возьмите компонент React раньше <CustomView x="20" y="10">
. Первоначально я бы сделал это так:
var x = 20;
var y = 10;
React.renderComponent(
<CustomView x={x} y={y} />,
document.getElementById('view-container')
);
Теперь, когда я хочу обновить CustomView в любое время x
, как мне следует продолжить? Предполагается, что React является альтернативой привязке данных, которую вы найдете в Angular и Ember, без использования двухсторонней привязки, поэтому как это сделать? Как сообщить CustomView
следить за x
и автоматически перерисовывать при изменении?
Естественно, просто присваивая x новое значение ничего не делает.
Я знаю, что существует метод setState
, но мне все же вручную нужно это назвать, правильно? Поэтому, если бы я работал с представлением React и моделью Backbone, код мог выглядеть примерно так:
// Data model: Backbone.js
var model = new Backbone.Model({text: "Please help! :)"});
// Create view class
var View = React.CreateClass({
render: function() {
return (
<p>{this.props.text}</p>
);
}
});
// Instantiate new view
var view = React.renderComponent(
<View text={model.get("text")}>,
document.getElementById('view-container')
);
// Update view
model.on("change:text", function(model, newValue) {
view.setState({
text: newValue
});
});
// Change data
model.set("text", "I do not understand this ...");
Это похоже на действительно странную настройку, и я почти уверен, что это не может быть так, как вы должны это делать.
Мне бы хотелось, чтобы некоторые указатели помогли мне двигаться в правильном направлении.
Заранее благодарим за любые отзывы и помощь.
Ответы
Ответ 1
Неужели React полностью устраняет понятие HTML-шаблонов?
Да, в пользу объявления ваших просмотров с помощью JavaScript. Он также позволяет эффективной структуре DOM работать.
В примерах Стартового набора, похоже, есть функции JSX или React.DOM прямо в ваших классах представлений, которые кажутся мне немного грязными, и я вижу, что это немного выходит из-под контроля, как ваши взгляды растут по сложности.
Вы не должны позволять вашему представлению расти по сложности. Сделайте большие компоненты из небольших компонентов, и у вас не будет проблемы. Если вы чувствуете, что это становится сложным, вы всегда можете его реорганизовать.
Я знаю, что существует метод setState, но мне все же вручную нужно это назвать, правильно? Поэтому, если я работал с представлением React и моделью Backbone [...]
Вам следует искать "реагировать на позвоночник", и вы найдете несколько сообщений в блогах и примеры кода. Они часто используются вместе. Не стесняйтесь добавлять ссылки, которые вы нашли полезными здесь.
Ответ 2
Вы на правильном пути, но есть две вещи, которые нужно исправить. Один из них - ошибка, другой - предпочтительный шаблон.
Ошибка. В представлении вы используете this.props.text
(хорошо!), но вы используете setState
в прослушивателе модели. Это устанавливает значение this.state.text
, которое вы не используете, поэтому оно не будет работать. setState
должен "использоваться" только из самого компонента - для всех целей и целей, считайте его защищенным методом. Вместо этого существует функция setProps
, которая предназначена для использования только вне компонента.
Предпочтительный шаблон: использование setProps
в скором времени будет устаревшим, поскольку оно вызывает ряд тонких проблем. Лучше всего просто переделать весь компонент каждый раз. Правильный код в вашем случае:
// Data model: Backbone.js
var model = new Backbone.Model({text: "Please help! :)"});
// Create view class
var View = React.CreateClass({
render: function() {
return (
<p>{this.props.text}</p>
);
}
});
function rerender() {
React.renderComponent(
<View text={model.get("text")}>,
document.getElementById('view-container')
);
}
// Update view
model.on("change:text", function(model, newValue) {
rerender();
});
rerender();
Ответ 3
Спасибо за ответы, ребята,
Итак, могу ли я исправить предположение, что если я хочу, чтобы представления наблюдали модели данных, то, что мне в итоге, на самом деле довольно близко к коду представления Backbone, где вы подключаете прослушиватели событий в методе intialize
? Вот пример, который работает:
var model = new Backbone.Model({
text: "Hey there :)"
});
var TextBox = React.createClass({
getInitialState: function() {
return this.props.model.toJSON();
},
componentWillMount: function() {
this.props.model.on("change:text", function(model, newText) {
this.setState({
text: newText
});
}, this);
},
render: function() {
return (
<p>{this.state.text}</p>
);
}
});
React.renderComponent(
<TextBox model={model} />,
document.getElementById('view-holder')
);
Как я уже сказал, это работает по назначению. Представление повторно отображает всякий раз, когда изменяется свойство текста модели. Будет ли это рассматриваться как "Хороший" реактивный код, или я должен использовать его по-другому?