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>
    );
}
});

Не стесняйтесь, дайте мне знать, если есть лучший способ сделать это, но сейчас это именно то, что мне нужно. Надеюсь, что-то из всего этого будет полезно и кому-то еще.

Другие вопросы по тегам