【问题标题】:Is it possible to pass data up to withTracker directly from it's lower order component?是否可以直接从它的低阶组件将数据传递给 withTracker?
【发布时间】:2019-01-21 21:59:10
【问题描述】:

我正在使用 React、Meteor 和 react-meteor-data 组合的现有代码库。

在我尝试使用 withTracker 实现搜索功能之前,一切都比较顺利, React Select, 和 Meteor 的订阅功能。

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);

我在 Google 上四处搜索,发现将数据获取到 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()
    }
});

输入框组件

import { WriteableConnectionToCollection } from './connections/writeableconnection.js';

const InputFieldComponent = React.createClass({

    render() {
        <InputField 
            onInputChange={this.props.onChange}
        />
    }
}

export default WritableConnectionToCollection(InputFieldComponent);

这是用这个特定的包/框架组合做事的唯一方法,还是有一种我没有看到的更简单的方法?

【问题讨论】:

  • 我的第一次尝试是使用 ReactiveVar。但我还没有尝试在withTracker 中使用它们。你已经试过了吗?我认为它应该可以工作,因为 withTracker 中的所有反应数据源都应该触发函数的重新运行。
  • 我尝试使用 ReactiveVar,虽然我对 ReactiveVar 应该放在哪里有点困惑。由于每次发生变化时 withTracker 都会运行提供的函数,因此如果我在 withTracker 函数内部初始化 ReactiveVar,那么它会重新初始化为其初始值(未定义、null、''等)。如果我将 ReactiveVar.set 功能传递给低阶组件,那么它会更改,触发 withTracker,然后重新初始化。至少据我所知。
  • 您应该在加载时对其进行初始化(即,直接在进行 withTracker 调用的文件中,但超出其范围。之后发生的所有更改都应该是您打算引起更改的更改.

标签: reactjs meteor subscription meteor-react


【解决方案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()
        }
    })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 2019-09-05
    • 2015-05-11
    • 2011-04-22
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多