meteor / react-packages

Meteor packages for a great React developer experience
http://guide.meteor.com/react.html
Other
574 stars 159 forks source link

withTracker with async code #393

Open mfeuermann opened 1 year ago

mfeuermann commented 1 year ago

Hi developers,

I wanted to ask if it is possible to use the withTracker function call in combination with the asynchronous call that will be introduced in Meteor 3.0

I have a large application where I use the container architecture with React components Example of container...

`import { withTracker } from 'meteor/react-meteor-data'; import {useDeps} from '@beisen/storybook-mantra-core'; import _ from 'lodash';

import locales from '../components/locales.jsx'; import {Locales} from '/lib/collections';

export const depsMapper = (context) => ({ context: () => context });

const localesWT = withTracker(({context, id}) => {

const {Log, LocalState} = context();

let localesArray = Locales.find({language: 'en'}).fetch();

return { localesArray }; })(locales);

export default useDeps(depsMapper)(localesWT); `

In the withTracker function I would like to call asynchronously however currently the content is rendered and does not wait for await...

Can we expect the withTracker function to be modified for use with Meteor.callAsync ?

Thanks

Grubba27 commented 1 year ago

Currently, the way to go for using the async tracker is what we have documented in the react-meteor-data docs, which uses the Suspense API.

The following code was taken from the docs:

import { useTracker } from 'meteor/react-meteor-data/suspense'
import { useSubscribe } from 'meteor/react-meteor-data/suspense'

function Tasks() { // this component will suspend
  useSubscribe("tasks");
  const { username } = useTracker("user", () => Meteor.user())  // Meteor.user() is async meteor 3.0
  const tasksByUser = useTracker("tasksByUser", () =>
          TasksCollection.find({username}, { sort: { createdAt: -1 } }).fetchAsync()) // async call
  );

  // render the tasks
}
mfeuermann commented 1 year ago

Thank you for the information, is there also a suspension implementation planned for withTracker ? The thing is that we use container pattern in our application... The question is whether it is planned to redesign it in the future Thanks for info Marek

Grubba27 commented 1 year ago

Got! I have not talked about having a suspense version of withTracker with @radekmie, but I think we can discuss this. Will bring it in our next meeting. Will keep you updated

mfeuermann commented 1 year ago

OK thank you, by the way I made a minor adjustment and it seems to work fine. Unfortunately I don't know TS so it's in JS. But it would be great if it could be delivered directly to the code. Thank you, I appreciate your work.

import React, { forwardRef, memo } from 'react';
import { useTracker } from 'meteor/react-meteor-data/suspense';

export const withTracker = (options) => {
  return (Component) => {
    const getMeteorData = typeof options === 'function' ?
      options :
      options.getMeteorData;

    const WithTracker = forwardRef((props, ref) => {
      const data = useTracker('', () => getMeteorData(props) || {});
      // const data = {};
      return (
        <Component ref={ref} {...props} {...data} />
      );
    });

    const { pure = true } = options;
    return pure ? memo(WithTracker) : WithTracker;
  };
};