我想用React.js创建一个应用程序.我希望它可以从外部世界轻松定制(例如通过编写用户脚本).我试图使用的想法是在根元素状态(如sidebarItems
或playlistCreatedHooks
)中创建一些特殊属性,因此addon开发人员可以在那里添加一些东西.我的问题是:这是一个很好的方法,是否有正确的方法来实现类似于我的目标,最后,插件开发人员将如何访问这些道具?
一种选择是可观察的.基本上它是一个对象,你可以听取变化,并创建一个变化.您还可以在data.playlists上发出其他事件,例如'add'事件,以创建您想要提供的api.
// data.js
var data = {
sidebarItems: Observable([]),
playlists: Observable([])
};
// app.js
var App = React.createComponent({
mixins: [data.sidebarItems.mixin("sidebar")],
render: function(){
return this.state.sidebar.map(renderSidebarItem);
}
});
/// userscript.js
// causes the view to update
data.sidebarItems.set(somethingElse);
// run when someone does data.playlists.set(...)
data.playlists.on('change', function(playlists){
});
// an event you could choose to emit with data.playlists.emit('add', newPlaylist)
data.playlists.on('add', function(newPlaylist){
});
这是上面使用的Observable的示例(未经测试)实现,具有用于生成反应组件mixin的额外函数.
var events = require('events'); // or some other way of getting it
var Observable = function(initialValue){
var self = new events.EventEmitter();
var value = initialValue;
self.get = function(){ return value };
self.set = function(updated){
value = updated;
self.emit('change', updated);
};
self.mixin = function(key){
var cbName = Math.random().toString();
var mixin = {
getInitialState: function(){ var o = {}; o[key] = value; return o },
componentDidMount: function(){
self.on('change', this[cbName]);
},
componentWillUnmount: function(){
self.removeListener('change', this[cbName]);
}
}
mixin[cbName] = function(){
var o = {}; o[key] = value; this.setState(o);
};
return mixin;
}
return self;
}