javascript - 如何在 Flux Store 中对状态变量实现隐私保护?

标签 javascript reactjs getter-setter flux private-members

我有一个我正在使用的 Flux 模式的小型自制实现,只是为了更好地理解该模式。它工作得很好,我学到了很多东西!但是我遇到了一个我现在无法解决的问题。如果这有明显的解决方案,请提前致歉。

想象一下我的名为 ExampleStore 的简单 Store 和我的简单组件 ExampleComponent。其中有:

_exampleState

getExampleState()

setExampleState()

在 ExampleComponent 中,保持更新:

_onChange: function() {
    setState({exampleState: ExampleStore.getExampleState()})
}

在 ExampleStore 中,在发送操作后我使用 setter:

setExampleState(newStateFromDispatchedAction);

这非常有效。数据按应有的方式流动。但我有一个问题,因为打破这种模式似乎很容易,因为我的 Store 中的 _exampleState 没有强制执行隐私。因为我有 _exampleState 的 getter 和私有(private) setter 方法,所以我想以某种方式对变量实现更多隐私似乎很自然。有没有一种我忽略的绝妙方法可以做到这一点?

就像现在一样,例如,如果我在 ExampleComponent 中执行(我不会这样做,但我可以):

this.state.exampleState = {field:'example'}
//doing this
this.state.exampleState.field = 'example2';
//changes the store _exampleState to {field:'example2'}

我直接更改了 ExampleStore 中 _exampleState 的值,没有使用 setter。这看起来很危险(并且让我质疑为什么我首先要有一个私有(private) setter/public getter)。这个问题是在处理一个讨厌的错误之后出现的,在这个错误中,我使用的库直接修改了状态变量,因此在 Store 中。

是否有一些我忽略的好方法来对我的 Store 中的状态变量实现隐私保护,以便它们不能通过它们在 ExampleComponent 中的引用直接更改?抱歉,如果这是一个愚蠢的问题并且我忽略了一些简单的事情,谢谢您的帮助!

最佳答案

请注意,Flux 哲学的基本原则之一是存储不应有(公共(public))setter。这意味着如果不在商店内部,您将无法修改商店的状态。

加强隐私的一种方法是将状态变量保持为私有(private),只让商店管理它们。

编辑:为了“加强”隐私,您还可以返回状态的深拷贝,如代码所示。

以下代码,基于official flux GitHub repository's flux-todomvc example , 突出思想:

var AppDispatcher = require('../dispatcher/AppDispatcher');
var AppConstants = require('../constants/AppConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

// This is a private state variable that can only be accessed in this file
var _exampleState = {/*...*/};

var ExampleStore = assign({}, EventEmitter.prototype, {
    EXAMPLE_STATE_CHANGED: 'EXAMPLE_STATE_CHANGED',
    // return a deep copy of your state so there is no way 
    // to modify the store's state by reference
    getExampleState: function() {
        return deepCopy(_exampleState);
    }

    /*...*/
};

// this is a private method (setter)
var _setExampleState = function(newExampleState) {
    _exampleState = newExampleState;
};

ExampleStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case AppConstants.CHANGE_EXAMPLE_STATE:
            _setExampleState(action.newExampleState);

            ExampleStore.emit(ExampleStore.EXAMPLE_STATE_CHANGED);

            break;
    }
});

// the implementation of deepCopy is a developer's choice
// this version of it is very inefficient
var deepCopy = function(obj) {
    return JSON.parse(JSON.stringify(obj));
}

module.exports = ExampleStore;

Facebook 官方示例是理解如何实现核心 Flux 概念的好方法。

编辑:这是一种“强制”状态变量隐私的方法,但由于明显的效率损失而不鼓励这样做。我想这里的主要思想是,即使在某些情况下您可以这样做,但通过引用更改商店的状态只是反对 Flux。重要的是要注意,这种强制执行在许多大型图书馆中并不现实。例如,在 React 中,可以直接修改组件的状态,尽管完全不推荐这样做。

关于javascript - 如何在 Flux Store 中对状态变量实现隐私保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35000541/

相关文章:

javascript - 如何不仅将 id 而且将完整对象传递到数组列表中

javascript - 数组的随机排序

python - 在 Python 中更新可变变量时自动执行操作

java - 使用调用自定义 getters/setters 的公共(public)变量/成员

c - C 中的虚假 getter/setter 函数返回错误值

javascript - 输入类型单选按钮已选中 else 语句在 jquery 中不起作用

javascript - ESLint 和普通控制台错误有什么区别?

css - 将输入标签的值传递给搜索按钮标签 - ReactJS

javascript - 如何使用BURSTS获取BURST账户余额?

reactjs - 如何使用异步请求服务器渲染 redux 应用程序?