React + Reflux:将变量传递给数据存储

时间:2014-12-22 16:58:24

标签: reactjs refluxjs

我正在建立一个React + Reflux应用程序,除其他外,它允许创建/删除/编辑类别。到目前为止,我能够显示所有类别,并通过关联的存储和操作处理React组件中类别的创建/删除。这一切都很好,更新数据库并按预期重新呈现组件。我的关键点是尝试深入研究特定的现有类别以进行编辑。

认为我不知何故需要将类别ID传递给商店,然后通过ajax调用将其传递给php / sql查询以获取/设置特定于该特定的数据类别。如果我完全绕过商店并将ajax调用放在组件本身中,我可以通过带有React-router的url参数使其工作(当然不会自动重新渲染)但我还没有能够弄清楚如何通过商店实现这一目标。

换句话说,这或多或少有效:

  • " ManageCategories" React组件使用CategoryStore列出所有类别,每个类别都包含在一个锚类标记中,该标记将类别ID传递给" ManageCategory"路径/元件
  • " ManageCategory" component在其getInitialState方法中的ajax调用中直接使用类别Id param来显示特定于该类别的数据

但是,我认为以下是更正确的反流方式,但我不确定如何让它工作:

  • " ManageCategories"与上述相同的组成部分
  • " ManageCategory"以某种方式将其类别ID参数传递给CategoryStore的组件(或者可能是另一个" IndividualCategoryStore"?),它仅返回特定于该类别的数据并处理对该类别的更新/编辑

通过在" ManageCategory&#34的getInitialState方法中调用的CategoryStore中添加一个新方法(" getCategoryData"),我得到了一种笨重的版本。 ;组件并传递categoryId参数。这导致所有类别的闪光(来自CategoryStore的getDefaultData),然后是正确的单一类别列表(来自组件的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 个答案:

答案 0 :(得分:2)

最后在这里发表我的问题后,我想我可能已经弄清楚我一直误入歧途的地方。我正在考虑将类别ID传递给商店来过滤其中的数据,而我真正需要做的就是从商店中获取完整的数据集合并在组件中有选择地使用它。

因此,一旦将catId作为url参数传递给ManageCategory组件,我需要做的就是根据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>
    );
}
});

如果有更好的方法,请随时告诉我,但现在这正是我所需要的。希望所有这些内容对其他人也有帮助。