是否可以直接从其低阶组件将数据传递到withTracker?

时间:2018-08-15 01:14:48

标签: reactjs meteor subscription meteor-react

我正在使用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);

这是使用这种特殊的包装/框架组合的唯一方法吗?还是我没有看到更简单的方法?

1 个答案:

答案 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()
        }
    })
}