目前我知道至少有三種方式將新數據傳遞給一個組件:
- 重新渲染組件。不要擔心這種方法的效率,因爲React似乎處理得很好。有關於此的好文章:Change And Its Detection In JavaScript Frameworks和Updating with React.render
- 使用PubSub允許在數據更改時通知組件(在How to communicate between React components文章中可找到一些有用的示例)。
- 有回調綁定(見下面的第三jsfiddles)
對於我被StevenH答案激發了第三個選項,並延長了一點。 請檢查我的執行j sfiddle.net/kb3gN/12002/。
var Data = { value: 1 };
var dataChange = function(callback){
if(callback){
callback(Data);
setInterval(function(){
Data.value++;
callback(Data);
}, 1000);
}
return Data;
};
var World = React.createClass({
render: function() {
return <strong>{this.props.data.value}</strong>;
}
});
var Hello = React.createClass({
getInitialState: function() {
return {
data: this.props.dataChange()
};
},
componentDidMount: function() {
this.props.dataChange(this.updateHandler)
},
updateHandler: function(data) {
this.setState({
data: data
});
},
render: function() {
return (
<div>
Value: <World data={this.state.data} />
</div>
);
}
});
React.renderComponent(<Hello dataChange={dataChange} />, document.body);
此外,還有一個擴展版本jsfiddle.net/kb3gN/12007。
function ListenersService(){
var listeners = {};
this.addListener = function(callback){
var id;
if(typeof callback === 'function'){
id = Math.random().toString(36).slice(2);
listeners[id] = callback;
}
return id;
}
this.removeListener = function(id){
if(listeners[id]){
delete listeners[id];
return true;
}
return false;
}
this.notifyListeners = function(data){
for (var id in listeners) {
if(listeners.hasOwnProperty(id)){
listeners[id](data);
}
}
}
}
function DataService(ListenersService){
var Data = { value: 1 };
var self = this;
var listenersService = new ListenersService();
this.addListener = listenersService.addListener;
this.removeListener = listenersService.removeListener;
this.getData = function(){
return Data;
}
setInterval(function(){
Data.value++;
listenersService.notifyListeners(Data);
}, 1000);
}
var dataSevice = new DataService(ListenersService);
var World = React.createClass({
render: function() {
return <strong>{this.props.data.value}</strong>;
}
});
var Hello = React.createClass({
getInitialState: function() {
return {
data: this.props.dataService.getData()
};
},
componentDidMount: function() {
this.props.dataService.addListener(this.updateHandler)
},
updateHandler: function(data) {
this.setState({
data: data
});
},
render: function() {
return (
<div>
Value: <World data={this.state.data} />
</div>
);
}
});
React.renderComponent(<Hello dataService={dataSevice} />, document.body);
此實現不完全以下隔離組件(因爲你好組件依賴於DataService在API)的想法,但它可以被進一步抽象,它的最大的應用程序開發人員,其具體應用的約定他的組件將遵循。例如,請參閱jsfiddle.net/kb3gN/12015(halloDataStatic對象和halloDataDynamic回調)中的第一個和第二個示例的組合
注意:示例中使用的ListenersService遵循Observer Pattern,在許多情況下,模式本身比專業人員更具缺點。但除此之外,我想通過這些示例展示的是,有一種數據與回調綁定的方式
<div id="static"></div>
<div id="dynamic"></div>
<script>
function ListenersService(){
var listeners = {};
this.addListener = function(callback){
var id;
if(typeof callback === 'function'){
id = Math.random().toString(36).slice(2);
listeners[id] = callback;
}
return id;
}
this.removeListener = function(id){
if(listeners[id]){
delete listeners[id];
return true;
}
return false;
}
this.notifyListeners = function(data){
for (var id in listeners) {
if(listeners.hasOwnProperty(id)){
listeners[id](data);
}
}
}
}
function DataService(ListenersService){
var Data = { value: 1 };
var self = this;
var listenersService = new ListenersService();
this.addListener = listenersService.addListener;
this.removeListener = listenersService.removeListener;
this.getData = function(){
return Data;
}
setInterval(function(){
Data.value++;
listenersService.notifyListeners(Data);
}, 100);
}
var dataSevice = new DataService(ListenersService);
var halloDataDynamic = function(callback){
var data = dataSevice.getData();
if(callback){
dataSevice.addListener(function(data){
callback(data);
});
}
return data;
};
var halloDataStatic = dataSevice.getData();
var World = React.createClass({
render: function() {
return <strong>{this.props.data.value}</strong>;
}
});
var Hello = React.createClass({
getInitialState: function() {
var data;
if(typeof this.props.halloData === 'function'){
data = this.props.halloData(this.updateHandler)
}
else data = this.props.halloData;
return {
data: data
};
},
updateHandler: function(data) {
this.setState({
data: data
});
},
render: function() {
return (
<div>
Value {this.props.name}: <World data={this.state.data} />
</div>
);
}
});
</script>
React.renderComponent(<Hello halloData={halloDataStatic} name="static"/>, document.getElementById('static'));
React.renderComponent(<Hello halloData={halloDataDynamic} name="dynamic"/>, document.getElementById('dynamic'));
您的模型層是否使用事件?如果是這樣,你可以使用它們來觸發渲染。 – krs
我已經添加了一個類似的問題關於使用React的骨幹模型,以及當模型更新時應如何更新視圖http://stackoverflow.com/questions/20371566/handling-backbone-model-collection-changes-in-react -js –
您是否找到解決方案? – copndz