React-Apollo: рекомендуемый способ подписки на несколько событий, не требующий обновления пользовательского интерфейса - PullRequest
1 голос
/ 24 мая 2019

Итак, я хочу подписаться на несколько событий для текущего зарегистрированного пользователя.

Я извлек подписки в отдельную функцию, которая обновляет состояние моего зарегистрированного пользователя изнутри и возвращает массив подписок.

Теперь я хотел бы знать, есть ли другой / лучший способ сделать это?

Это правильный / рекомендуемый способ решения этой проблемы?

Текущая реализация

export const subscribeToCurrentUserUpdates = (setLoggedUser) => {
  const friendRequestObserver$ = apolloClient.subscribe(
    { query: queries.NEW_FRIEND_REQUEST },
  );
  const followersUpdatesObserver$ = apolloClient.subscribe(
    { query: queries.FOLLOWERS_UPDATES },
  );
  const acceptedFriendRequestObserver$ = apolloClient.subscribe(
    { query: queries.ACCEPTED_FRIEND_REQUEST },
  );

  const friendRequestSubscription = friendRequestObserver$.subscribe({
    next: ({ data: { newFriendRequest } }) => {
      Alert.success(`${newFriendRequest.username} just sent you a friend request`);

      setLoggedUser((loggedUser) => {
        loggedUser.incomingFriendRequests.unshift(newFriendRequest._id);
      });
    },
    error: err => console.error(err),
  });

  const followersUpdatesSubscription = followersUpdatesObserver$.subscribe({
    next: ({ data: { followersUpdates: { follower, isFollow } } }) => {
      if (isFollow) {
        Alert.success(`${follower.username} is now following you`);
      }

      setLoggedUser((loggedUser) => {
        isFollow
          ? loggedUser.followers.unshift(follower._id)
          : loggedUser.followers.splice(loggedUser.followers.indexOf(follower._id), 1);
      });
    },
    error: err => console.error(err),
  });

  const acceptedFriendRequestSubscription = acceptedFriendRequestObserver$.subscribe({
    next: ({ data: { acceptedFriendRequest: newFriend } }) => {
      Alert.success(`${newFriend.username} just accepted your friend request!`);

      setLoggedUser((loggedUser) => {
        loggedUser.friends.push(newFriend._id);
        loggedUser.sentFriendRequests.splice(
          loggedUser.sentFriendRequests.indexOf(newFriend._id), 1,
        );
      });
    },
    error: err => console.error(err),
  });

  return [
    friendRequestSubscription,
    followersUpdatesSubscription,
    acceptedFriendRequestSubscription,
  ];
};

Способ подписки на мой компонент

const App = () => {
  const currentUserSubscriptionRef = useRef();

  useEffect(() => {
    if (loggedUser && !currentUserSubscriptionRef.current) {
      currentUserSubscriptionRef.current = subscribeToCurrentUserUpdates(
        setLoggedUser,
      );
    }
    if (!loggedUser && currentUserSubscriptionRef.current) {
      currentUserSubscriptionRef.current.forEach((subscription) => {
        subscription.unsubscribe();
      });
      currentUserSubscriptionRef.current = null;
    }
  }, [loggedUser, setLoggedUser]);
}
...