我正在使用React,Meteor和react-meteor-data组合的现有代码库中。
在我尝试使用withTracker实现搜索功能之前,一切都进行得比较顺利, React Select, 和流星的订阅功能。
import { CollectionAPI } from '../arbitrary_meteormongo_collection';
export const WriteableConnectionToCollection = withTracker(props => {
let connection = Meteor.subscribe('COLLECTION_NAME.searchByName', SEARCH_TEXT_HERE);
let isLoading = connection.ready();
return {
...props,
isLoading: isLoading,
collection: CollectionAPI.find().fetch()
}
})(PRESENTATIONAL_COMPONENT);
我四处搜寻,发现将数据发送到Meteor.subscribe的常见解决方案是使用URL参数之类的方法,尽管当我在现有代码库中工作时,此更改也需要在各个位置实现
我发现的另一种方法是通过跟踪父组件状态下的输入字段状态,将输入字段的值传递给父组件,尽管这显然打破了关注点分离的原理:
父组件
export const ParentComponent = React.createClass({
getInitialState() {
return {
inputFieldValue: undefined
}
},
onChange(change) {
this.setState(inputFieldValue);
},
render() {
return (
<Search
onChange={this.onChange}
inputFieldValue={this.state.inputFieldValue}
/>
}
}
withTracker HOC
import { CollectionAPI } from '../arbitrary_meteormongo_collection';
export const WriteableConnectionToCollection = withTracker(props => {
let connection = Meteor.subscribe('COLLECTION_NAME.searchByName', this.props.inputFieldValue);
let isLoading = connection.ready();
return {
...props,
isLoading: isLoading,
collection: CollectionAPI.find().fetch()
}
});
InputField组件
import { WriteableConnectionToCollection } from './connections/writeableconnection.js';
const InputFieldComponent = React.createClass({
render() {
<InputField
onInputChange={this.props.onChange}
/>
}
}
export default WritableConnectionToCollection(InputFieldComponent);
这是使用这种特殊的包装/框架组合的唯一方法吗?还是我没有看到更简单的方法?
答案 0 :(得分:1)
就像Christian Fritz had mentioned在原始问题下的评论中一样,我可以使用ReactiveVar来将输入传入和传出我的连接组件:
export const WritableConnection = function (subscriptionName, collectionAPI) {
/**
* ReactiveVar must be outside of withTracker. If the it was inside withTracker's scope,
* anytime a user would use .set(ANY_VALUE), it would overwrite whatever was in it first,
* and then re-initialize.
**/
const input = new ReactiveVar(undefined);
return withTracker(props => {
const connection = Meteor.subscribe(subscriptionName, input.get());
const isLoading = connection.ready();
return {
...props,
isLoading: isLoading,
collection: collectionAPI.find().fetch(),
setSearchText: (text) => input.set(text),
getSearchText: () => input.get()
}
})
}