React+Reflux: передача переменных в хранилища данных
Я создаю приложение React+Reflux, которое, помимо прочего, позволяет создавать / удалять / редактировать категории. До сих пор я мог отображать все категории и обрабатывать создание / удаление категорий в компоненте React через связанные хранилища и действия. Все это прекрасно работает, обновляет базу данных и повторно отображает компонент, как и ожидалось. Мой камнем преткновения является попытка перейти к конкретной существующей категории для ее редактирования.
Я думаю, что мне как-то нужно передать Id категории в хранилище, которое затем передаст его в php / sql-запрос через ajax-вызов, чтобы получить / установить данные, специфичные для этой конкретной категории. Если я вообще обойду хранилище и помещу ajax-вызов в сам компонент, я смогу заставить его работать через параметр url с React-router (без автоматического повторного рендеринга, конечно), но я не смог выяснить как это сделать через магазин.
Другими словами, это более или менее работает:
- Реагирующий компонент "ManageCategories", который использует CategoryStore для отображения всех категорий, каждая из которых обернута в тег привязки, который передает идентификатор категории вместе с маршрутом / компонентом "ManageCategory"
- Компонент "ManageCategory" использует параметр Id категории непосредственно в вызове ajax в своем методе getInitialState для отображения данных, относящихся к категории
Тем не менее, я думаю, что ниже приведен более правильный способ рефлюкса, но я не уверен, как заставить его работать:
- Компонент "ManageCategories" такой же, как и выше
- Компонент "ManageCategory", который каким-то образом передает свой параметр Id категории в хранилище категорий (или, может быть, в другой "IndividualCategoryStore"?), Который возвращает только данные, относящиеся к этой категории, и обрабатывает обновления / изменения этой категории.
Я смог получить своего рода неуклюжую версию этой работы, добавив новый метод ("getCategoryData") в хранилище категорий, который вызывается в методе getInitialState компонента "ManageCategory" и которому передается параметр categoryId. Это приводит к миганию всех категорий (из getDefaultData DataStore) с последующим правильным списком отдельных категорий (из getInitialState компонента).
Я чувствую себя довольно комфортно с концепциями React+Reflux, но на данный момент я думаю, что, скорее всего, я неправильно понимаю что-то фундаментальное. Работал над этой конкретной проблемой более недели, но ни один из найденных мной примеров / руководств / документов не посвящен конкретному вопросу передачи переменной в хранилище данных.
Действия:
var Actions = Reflux.createActions([
"createCategory",
"deleteCategory",
"editCategory"
]);
CategoryStore:
var CategoryStore = Reflux.createStore({
listenables: [Actions],
onCreateCategory: function(catName) {
// ajax call to create new category that calls updateCategories on success
},
onDeleteCategory: function(catId) {
// ajax call to delete category that calls updateCategories on success
},
updateCategories: function(){
$.ajax({
url: url + '?action=getAllCategories',
async: false,
dataType: 'json',
success: function(categoryData) {
this.categories = categoryData;
}.bind(this),
error: function(xhr, status, err) {
console.error(url, status, err.toString());
}.bind(this)
});
this.trigger(this.categories);
},
getDefaultData: function() {
$.ajax({
url: url + '?action=getAllCategories',
async: false,
dataType: 'json',
success: function(categoryData) {
this.categories = categoryData;
}.bind(this),
error: function(xhr, status, err) {
console.error(url, status, err.toString());
}.bind(this)
});
return this.categories;
}
});
Компонент категории:
var Category = React.createClass({
handleDeleteCategory: function() {
Actions.deleteCategory(this.props.id);
},
render: function() {
return (
<li className="category">
<IconButton icon="action-highlight-remove" onClick={this.handleDeleteCategory} />
<h5><a href={"/#/manage-category/" + this.props.id}>{this.props.name} ({this.props.id})</a></h5>
</li>
);
}
});
Компонент ManageCategories:
var ManageCategories = React.createClass({
mixins: [
Reflux.connect(CategoryStore, "categories")
],
getInitialState: function() {
return {
categories: []
};
},
handleCreateCategory: function() {
// category creation code
},
render: function() {
var categoryNodes = this.state.categories.map(function(category) {
return (
<Category name={category.name} id={category.id} />
)
});
return (
<div className="dev-tools-container">
<h1>Developer Tools</h1>
<div className="categories">
<h3>Categories</h3>
<ul>
{categoryNodes}
</ul>
<h4>Create New Category:</h4>
<form>
<label htmlFor="new-category-name">Category Name</label> <input type="text" id="new-category-name" /><br />
<PaperButton label="Create" primary={true} onClick={this.handleCreateCategory} />
</form>
</div>
</div>
);
}
});
Заранее спасибо за любые идеи или помощь.
1 ответ
После того, как я наконец разместил здесь свой вопрос, я думаю, что, возможно, понял, куда я сбился с пути. Я думал о том, чтобы передать Id категории в хранилище, чтобы отфильтровать в нем данные, когда все, что мне действительно нужно, - это взять полный сбор данных из хранилища и выборочно использовать его в компоненте.
Поэтому после того, как я направил его в компонент ManageCategory с catId, переданным в качестве параметра url, все, что мне нужно сделать, это отфильтровать данные на основе catId.
Например, однажды в компоненте ManageCategory я могу использовать lodash для фильтрации и выбора значения имени текущей категории, как показано ниже. Нет необходимости редактировать коллекцию данных, хранящихся в CategoryStore.
var ManageCategory = React.createClass({
mixins: [
Reflux.connect(CategoryStore, "categoryData")
],
getInitialState: function() {
return {
categoryData: []
};
},
render: function() {
var categoryName = _.chain(this.state.categoryData)
.filter({"id": this.props.params.catid})
.pluck("name");
return (
<div className="category-container">
<h1>{categoryName}</h1>
</div>
);
}
});
Не стесняйтесь, дайте мне знать, если есть лучший способ сделать это, но сейчас это именно то, что мне нужно. Надеюсь, что-то из всего этого будет полезно и кому-то еще.