我有一个我正在使用的 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/