0

I am an angular dev who is new to React. I use observables to manage all my states as that is what I am familiar with. I am trying to figure out the best way to write a custom observable hook that only subscribes when the user clicks a button

I am trying to implement something like this:

const addMovieHandler = useCallback((movie) => {
setIsLoading(true);
addMovie$(movie).subscribe((data) => {
  console.log(data);
  fetchMovies()
});
 }, [fetchMovies]);

It works but it seems hacky and I do not know where to put the unsubscribe

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
Isidbigi
  • 5
  • 1
  • 4
  • how would you want the hook to be used? any code usage example? – Fan Cheung May 22 '22 at 08:15
  • I have edited the post to show what I am trying to write – Isidbigi May 22 '22 at 08:31
  • I only want to add the movies when a button (addMovieHandler) is clciked – Isidbigi May 22 '22 at 08:33
  • It's hacky indeed. Generally side effects (subscribe) would go to useEffect, but in this case it's unclear. How is addMovieHandler used? The code looks troublesome from Angular perspective too. Observables aren't supposed to be composed with async ops like fetchMovies like that. Please, provide https://stackoverflow.com/help/minimal-reproducible-example for your case – Estus Flask May 22 '22 at 10:02

1 Answers1

0

You can make use of Subject as event emitter and subscribe to it in useEffect() - something like componentDidMount and unsubscribe() upon unmount to avoid memory leak. useRef() should be used so there is always one subject instance across the entire component lifecycle

const onAddMovie=useRef(new Subject).current

// Similar to angular OnNgInit 
useEffect(()=>{
   const sub=>onAddMovie.pipe(
     switchMap(()=>fetchMovies())
     tap(()=>... side effect like setState)
   ).subscribe()
   return ()=>sub.unsubscribe()

},[])

<Button click={()=>onAddMovie.next()}> add movie </Button>
Fan Cheung
  • 10,745
  • 3
  • 17
  • 39