简体   繁体   中英

Where should I put the Meteor subscription in a tracker-react container?

Using Meteor 1.3, I have a react component wrapped with tracker-react. I set it up like the example on tracker-react github

class TaskIndex extends TrackerReact(React.Component) {

  constructor() {
    super();
    this.state = {
      subscription: {
        tasks: Meteor.subscribe("tasks", Meteor.userId() )
      }
    }
  }

  componentWillUnmount() {
      this.state.subscription.tasks.stop();
  }

  getTasks() {
      return  Tasks.find().fetch()
  }

  render() {
   //... displays the tasks
  }

}

The subscription passes the current user to get the right tasks. The problem is, when I logout, and Meteor.userId() becomes undefined, the subscription is not updated. The tasks stay visible until I refresh the page. The reverse is true when I login: no tasks appear when Meteor.userId() becomes valid.

If instead I put the subscription in the getTasks() method as below, it behaves correctly, but feels wrong. Should the subscription be in one of the lifecycle methods? How do I stop the subscription, do I even need to?

  getTasks() {
      Meteor.subscribe("tasks", Meteor.userId() );
      return  Tasks.find().fetch()
  }

Thanks

Answer courtesy of the author on github issues

Hey, yes, that is because it is in the constructor, which is run once before the component is mounted. If you want to have a subscription that is reactive while the component is rendered, it needs to be in the render block.

... or in some function that is called by the render block.

render() {
   Meteor.subscribe("tasks", Meteor.userId() )
   return (
      // some jsx
   )
}

I have done the following to update a subscription based on the actively signed in user. I honestly always had the same question you have, and could never find an "official" answer.

var userIdTracker;

class TaskIndex extends TrackerReact(React.Component) {

    constructor() {

        super();

        userIdTracker = Tracker.autorun(() => {
            this.setState({
                subscription: {
                    tasks: Meteor.subscribe("tasks", Meteor.userId())
                }
            });
        });

    }

    componentWillUnmount() {
        // Make sure you stop the autorun or it will continue to exist
        userIdTracker.stop();
        this.state.subscription.tasks.stop();
    }

    getTasks() {
        return  Tasks.find().fetch()
    }

    render() {
        //... displays the tasks
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM