Architecture 从外部访问React状态
我想使用React.js制作一个应用程序。我希望它可以从外部世界轻松定制(例如,通过编写用户脚本)。我尝试使用的想法是在根元素状态中创建一些特殊属性(如Architecture 从外部访问React状态,architecture,reactjs,Architecture,Reactjs,我想使用React.js制作一个应用程序。我希望它可以从外部世界轻松定制(例如,通过编写用户脚本)。我尝试使用的想法是在根元素状态中创建一些特殊属性(如sidebarItems或playlaycreatedhooks),以便插件开发人员可以在那里添加一些东西。我的问题是:这是一个好方法吗?有正确的方法吗™ 为了实现类似于我的目标,最后,插件开发人员将如何访问这些道具?一个选项是可观察。基本上,它是一个对象,您可以在其上收听更改,并在其上创建更改。您还可以在data.playlists上发出其他事
sidebarItems
或playlaycreatedhooks
),以便插件开发人员可以在那里添加一些东西。我的问题是:这是一个好方法吗?有正确的方法吗™ 为了实现类似于我的目标,最后,插件开发人员将如何访问这些道具?一个选项是可观察。基本上,它是一个对象,您可以在其上收听更改,并在其上创建更改。您还可以在data.playlists上发出其他事件,如“添加”事件,以创建要提供的api
//data.js
风险值数据={
侧重元素:可观察([]),
播放列表:可观察([])
};
//app.js
var App=React.createComponent({
mixin:[data.sidebarItems.mixin(“侧栏”)],
render:function(){
返回这个.state.sidebar.map(renderSidebarItem);
}
});
///userscript.js
//使视图更新
data.sidebarItems.set(somethingElse);
//当有人处理数据时运行。播放列表。设置(…)
data.playlists.on('change',功能(播放列表){
});
//您可以选择使用data.playlists.emit('add',newPlaylist)发出的事件
data.playlists.on('add',函数(newPlaylist){
});
下面是上面使用的Observable的一个示例(未测试)实现,带有一个用于生成react组件mixin的额外函数
var events=require('events');//或者其他的方式得到它
var可观测=函数(初始值){
var self=new events.EventEmitter();
var值=初始值;
self.get=function(){return value};
self.set=功能(已更新){
价值=更新;
self.emit('change',updated);
};
self.mixin=函数(键){
var cbName=Math.random().toString();
变量mixin={
getInitialState:function(){var o={};o[key]=value;返回o},
componentDidMount:function(){
self.on('change',此[cbName]);
},
componentWillUnmount:function(){
self.removeListener('change',此[cbName]);
}
}
mixin[cbName]=函数(){
var o={};o[key]=value;this.setState(o);
};
返混;
}
回归自我;
}
这是我的解决方案。由于这种可观察性,React组件的状态会自动更新(其结果,如重新渲染组件),并且您甚至可以通过.on
方法监听React之外的更改
var eventEmitter = {
_JQInit: function() {
this._JQ = jQuery(this);
},
emit: function(evt, data) {
!this._JQ && this._JQInit();
this._JQ.trigger(evt, data);
},
once: function(evt, handler) {
!this._JQ && this._JQInit();
this._JQ.one(evt, handler);
},
on: function(evt, handler) {
!this._JQ && this._JQInit();
this._JQ.bind(evt, handler);
},
off: function(evt, handler) {
!this._JQ && this._JQInit();
this._JQ.unbind(evt, handler);
}
};
var Observable = function(initialValue, name) {
var self = eventEmitter;
var name = name;
var obj = {
value: initialValue,
ops: self
};
self.get = function() {
return obj.value
};
self.set = function(updated){
if(obj.value == updated)
return;
obj.value = updated;
self.emit('change', updated);
};
self.mixin = function() {
var mixin = {
getInitialState: function() {
var obj_ret = {};
obj_ret[name] = obj;
return obj_ret;
},
componentDidMount : function() {
self.on('change', function() {
var obj_new = {};
obj_new[name] = obj;
this.setState(obj_new);
}.bind(this));
}
};
return mixin;
};
return self;
};
示例(使用它显示另一组件上的警报):
//可观测初始
alert_msg=可观察(“”,“alertmsg”)
var ConfirmBtn=React.createClass({
mixin:[警报消息.mixin()],
HandleConfig:函数(e){
e、 预防默认值();
this.state.alertmsg.ops.set(null);
如果(!$(“#cgv')。是(“:选中”)){
this.state.alertmsg.ops.set('请接受我们的条件条款');
返回;
}
}
}
var AlertPayment=React.createClass({
mixin:[警报消息.mixin()],
render:function(){
var style=(this.state.alertmsg==null)?{display:'none'}:{display:'block'};
返回(
{this.state.alertmsg.value}
);
}
});
希望能有帮助
var ConfirmBtn = React.createClass({
mixins: [alert_msg.mixin()],
handleConfirm: function(e) {
e.preventDefault();
this.state.alertmsg.ops.set(null);
if(! $('#cgv').is(':checked')) {
this.state.alertmsg.ops.set('Please accept our terms of conditions');
return;
}
}
}
var AlertPayment = React.createClass({
mixins: [alert_msg.mixin()],
render: function() {
var style = (this.state.alertmsg === null) ? {display: 'none'} : {display: 'block'};
return (
<div style={style} className="alertAcceptTerms">
{this.state.alertmsg.value}
</div>
);
}
});