Correct use of Tracker in react native component?

Hi everyone, I’m having some trouble finding use cases I can understand for Tracker in react native. I am currently using the https://www.npmjs.com/package/@socialize/react-native-meteor package. Currently my component looks like this:

export default class Home extends Component {

    state = { 
        loggedIn: Meteor.userId(), // check if user is logged in, initial state
    };

    render() {........

but soon realized it wasn’t reactive in finding if user was logged in - especially when I call ’ Meteor.logoutOtherClients();’

I know I’m supposed to use Tracker, but im not sure what the correct way of implementing it is? Do I put it in a componentDidMount() ? I would like to make the state reactive so I can show a particular page or not.

Thank you in advance

EDIT: Or should I get rid of the ‘export’ and instead put it inside (found from example):

export default createContainer( () => {
//Tracker Here
  Meteor.subscribe('getAllNumbers')
  return {
    phoneNumbers: Meteor.collection('phoneNumbers').find({})
  }
}, App) 

Working with:

export default withTracker(params=>{
  return {
            loggedIn: Meteor.userId(),
  };
})(App);

A cleaner variant is now allowed by using Hooks and functional components, thus allowing you to delete those frankly annoying HOC component wrappers.

You define this function once:

import { Tracker } from 'meteor/tracker';
import { useState, useEffect, useCallback } from 'react';

export default function withTracker(reactiveFn, dependencies) {
    const [trackerData, setTrackerData] = useState(null);
    const callback = useCallback(reactiveFn, dependencies);

    useEffect(() => {
        let computation;
        Tracker.nonreactive(() => {
        computation = Tracker.autorun(() => setTrackerData(callback()));
        });
        return () => computation.stop();
    }, [callback]);

    return trackerData;
}

And then use it in your component like this:

import React, { useState } from 'react';
import withTracker from './withTracker';

function Home(props) {

  const [otherStateValue, setOtherStateValue] = useState('foo');
  
  const loggedIn = withTracker(() => !!Meteor.userId());
  const phoneNumbers = withTracker(props => {
    Meteor.subscribe('phonenumbers.by_user_id', props.userId);
    return PhoneNumbers.find({}).fetch();
  }, [props.userId]);
  return <div>
             {loggedIn ? {dosomethingwith(phoneNumbers) : 'NotLoggedIn!'}
         </div>;
}

Taken from here: React Hooks - state and lifecycle methods without a class (React 16.7.0-alpha)

@rhywden : That code you posted was an early attempt, the actual PR for react-meteor-data has a safer version.

Also, by convention react hooks are named useXxx() - this applies to the ones that ship with react (useState, useEffect…), and to custom ones you build on top of them.
withTracker() is more the name of a HOC, and useTracker() more the name of a hook.

Could you maybe post the cleaned-up version? Because I can’t make heads or tails out of the PR what with the various additions and subtractions?

I really don’t need the fallback to HOC :wink:

I don’t really feel like copy/pasting the code of an ongoing PR all over the place :wink:
But you can simply grab the content of the useTracker.js file at https://github.com/meteor/react-packages/pull/262/files

1 Like

Thank you for that. Just one quick question, though:

How would one use useTracker in case of no needed exterior dependencies on a prop? Like, for example, getting all users (with the proper publication server-side, of course!)? Would it look like this?

const users = useTracker(() => {
        Meteor.subscribe('all_users');
        return Meteor.users.find({}).fetch();
    },[]);

Yep, sounds correct.

1 Like

How is this situation in 2022? I’m currently using withTracker from @meteorrn/core

However, I’d love to use Hooks here as well, so is it possible to use the useTracker Hook in React Native same way as for usual web dev (from meteor/react-meteor-data)?

EDIT: found the solution! - It is part of Meteor in @meteorrn/core. There is a closed issue here: Getting error while using useTracker hook · Issue #60 · TheRealNate/meteor-react-native · GitHub
Unfortunately there is no documentation about this yet