我想做这样的事情
var App = React.createClass({
render: function() {
return (
<CountryAutoComplete />
)
}
});
不同的应用
var App2 = React.createClass({
render: function() {
return (
<CountryAutoComplete />
)
}
});
这是一个简单的自动填充(不是整个文件)
var AutoComplete = React.createClass({
componentDidMount: function() {
$(this.getDOMNode()).typeahead(this.props);
},
render: function() {
return (
<input type="text" class="typeahead" onChange={this.props.onChange} />
);
}
});
CountryAutoComplete将是这样的自包含。
var CountryAutoComplete = React.createClass({
search: function(country, process) {
// Make an ajax call and return the data. No other components needed
$.ajax({
url: '/country' + '?search=' + country
}).then(process);
},
render: function() {
return (
<AutoComplete onChange={this.props.onChange} source={this.search} />
);
}
});
根据Flux文档,看起来任何带有API调用的内容都需要通过
行动 - &gt; API - &gt;调度员 - &gt;商店 - &gt;成分
这使CountryAutoComplete与特定应用程序绑定,因为操作,Dispatcher和存储特定于App。使这个组件可以跨应用程序重用的最佳方法是什么?
答案 0 :(得分:10)
你不应该在自动完成组件中进行任何ajax调用(因为你说你想让它可重用)。我通常将所有数据请求调用/ api用法放入一个单独的模块中,该模块使用promises来阻止多个请求
因此,我们的想法是让您的自动完成组件从父组件中获取选项/数据。该父组件最初可以从存储中获取数据,并侦听该存储中的任何更改事件,并在需要时更新其状态。将this.state.options
(或您用于选项的任何州)作为自动完成的道具传递。当用户键入内容时,使用查询发出操作。该操作轮流应该调用API和Dispatcher,更新商店,并为商店发出更改事件。您的父组件将分别更新其状态,并将作为prop。
这样的事情:
var App = React.createClass({
getInitialState: function() {
return {
// default results/data?
data : Store.getResults('')
};
},
storeChangeListener: function(newData) {
this.setState({
data: newData
});
},
componentDidMount: function() {
this.listenTo(Store, this.storeChangeListener);
},
onChange: function(query) {
// on search change
Actions.getResults(query);
},
render: function() {
return (
<AutoComplete data={this.state.data} onChange={this.onChange} />
);
}
});
在店里,这样的事情:
var countryAPI = require('./countryAPI')
var Store = {
getResults: function(query) {
// check cache if any? otherwise make call
if(this.cache[query]) {
return this.cache[query];
} else {
countryAPI.search(query).then(this.update);
}
},
update: function(data) {
AppDispatcher.dispatch({
type: "DATA_FROM_SERVER",
payload: {id: query, data: result}
})
},
handleDataFromServer: function(action) {
//store into cache/store
this.cache[action.payload.id] = action.payload.result;
this.emit("change"); // re-render app on whoever is listening to this store
}
}
和你的api例如
var countryAPI = {
search: function(query) {
// check to make sure this promise isnt called before
if(!this.allPromises[query]) {
this.allPromises[query] = $.ajax({
url: '/country' + '?search=' + country
})
}
return this.allPromises[query];
}
}
总结一下,实际的API实现imo应该与flux操作分开,它们应该只关注Web-API特定的东西,并且让flux actions / stores在数据流动时单独处理响应:
Component --> Listens to Store
--> Calls Load Action --> Show Pending State/Optimistic Updates --> Dispatcher --> Store --> changeEvent (Component will be listening and be updated)
--> countryAPI.load()
onLoadSuccess --> Dispatcher --> Store --> changeEvent --> Component
onLoadError --> Dispatcher --> Store --> changeEvent --> Component