xcarpentier / rn-tourguide

🚩Make an interactive step by step tour guide for your react-native app (a rewrite of react-native-copilot)
https://xcarpentier.github.io/rn-tourguide/
Other
733 stars 213 forks source link

Passing tourKey to useTourGuideController returns undefined eventEmitter #141

Open nicencina opened 1 year ago

nicencina commented 1 year ago

All of the documentation that I have read indicates that multiple tours across different tabs should work as:

import { TourGuideZone, useTourGuideController } from 'rn-tourguide'
const {
  canStart, // <-- These are all keyed to the tourKey
  start, // <-- These are all keyed to the tourKey
  stop, // <-- These are all keyed to the tourKey
  eventEmitter, // <-- These are all keyed to the tourKey
  tourKey, // <-- Extract the tourKey
} = useTourGuideController(**_unique_tour_key_**)

return (
  <TourGuideZone
    tourKey={tourKey} // <-- Pass in the tourKey
    zone={2}
    text='Check on your results'
  >
    {/** Children */}
  </TourGuideZone>

however when I pass a _unique_tourkey to useTourGuideController it returns an undefined eventEmitter. Calling eventEmitter then returns an error cannot read property 'on' undefined. (The eventEmitter is perfectly valid if I do not pass a _unique_tourkey, btw)

I can get past this on subsequent tabs/tours by pulling the TourGuideZone from the hook (using a _unique_tourkey) and using that TourGuideZone to invoke a tab-specific tour, but then I don't have access to an eventEmitter, which I need in order to set page-specific handlers (like setting a flag to not show this tour again after onboarding).

I can get past this outside of the rn-tourguide by setting the do-not-show-again flag within the useEffect method, such as:

useEffect(() => {
  if(canStart) {
    start();
    _setDoNotShowAgainFlag()_;
  }
}, [canStart])

but I thought that I'd check to see if I could use the component as specified in the documentation first before working my way around it (also, I can't be sure that the user actually saw the whole tour). Is anyone else experiencing issues when passing in a _unique_tourkey?

RuFang-21 commented 1 year ago

My issues was cannot click on the next even on second screen i got the tourkey

nhanptse05568 commented 1 year ago

same issue here, i fixed it by pass the eventEmitter into useEffect's dependency like this `useEffect(() => { eventEmitter?.on('start', handleOnStart); eventEmitter?.on('stop', handleOnStop); eventEmitter?.on('stepChange', handleOnStepChange);

return () => {
  eventEmitter?.off('start', handleOnStart);
  eventEmitter?.off('stop', handleOnStop);
  eventEmitter?.off('stepChange', handleOnStepChange);
};

}, [eventEmitter]);`

mritul commented 8 months ago

@nicencina @RuFang-21 Did you manage to fix it ? I'm unable to move to the next stage when I do what @nhanptse05568 mentioned

nicencina commented 8 months ago

@mritul I just got around it by passing a unique_tour_key and not calling an eventEmitter or tourkey. I manage state and history in my persistence layer.

It looks like:

    const {
        canStart,
        start,
        stop,
        TourGuideZone,
        TourGuideZoneByPosition,
        // eventEmitter, <--- can't use if passing unique lib key
        // tourKey <--- can't use if passing unique lib key
    } = useTourGuideController('your_unique_library_key_here');

In my canStart useEffect call I set a flag that this tour was seen. I would prefer to use a finer approach by having access to the eventEmitter to know precisely when the tour is complete, but I opted for a more brute force approach, which still gets the job done.

mritul commented 8 months ago

Seems convincing @nicencina. I'll give it a shot. Thank you for taking the time !