I have custom hook named useIsUserSubscribed that checks to see a specific user is subscribed. It returns true if the user is subscribed and false if the user is not subscribed...
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { checkSubscription } from "../services";
// this hook checks if the current user is subscribed to a particular user(publisherId)
function useIsUserSubscribed(publisherId) {
const [userIsSubscribed, setUserIsSubscribed] = useState(null);
const currentUserId = useSelector((state) => state.auth.user?.id);
useEffect(() => {
if (!currentUserId || !publisherId) return;
async function fetchCheckSubscriptionData() {
try {
const res = await checkSubscription(publisherId);
setUserIsSubscribed(true);
} catch (err) {
setUserIsSubscribed(false);
}
}
fetchCheckSubscriptionData();
}, [publisherId, currentUserId]);
return userIsSubscribed;
}
export default useIsUserSubscribed;
...I have a button using this hook that renders text conditionally based on the boolean returned from useIsUserSubscribed...
import React, { useEffect, useState } from "react";
import { add, remove } from "../../services";
import useIsUserSubscribed from "../../hooks/useIsUserSubscribed";
const SubscribeUnsubscribeBtn = ({profilePageUserId}) => {
const userIsSubscribed = useIsUserSubscribed(profilePageUserId);
const onClick = async () => {
if (userIsSubscribed) {
// this is an API Call to the backend
await removeSubscription(profilePageUserId);
} else {
// this is an API Call to the backend
await addSubscription(profilePageUserId);
}
// HOW CAN I RERENDER THE HOOK HERE!!!!?
}
return (
<button type="button" className="sub-edit-unsub-btn bsc-button" onClick={onClick}>
{userIsSubscribed ? 'Subscribed' : 'Unsubscribed'}
</button>
);
}
After onClick I would like to rerender my the useIsUserSubscribed hook So that my button text toggles. Can this be done? Should I use a different approach?
SubscribeUnsubscribeBtn has a dependency on useIsUserSubscribed, but useIsUserSubscribed don't depend on anything from SubscribeUnsubscribeBtn.
Instead, useIsUserSubscribed is keeping a local state. You have a couple of choices here:
useIsUserSubscribed that you need to change its internal state.For 1)
const [userIsSubscribed, setUserIsSubscribed] = useState(null);
move this state to Redux store and use it with useSelector.
For 2), return an array of value and callback from the hook, instead of just the value. It will allow you to communicate from component back into the hook.
In useIsUserSubscribed,
return [userIsSubscribed, setUserIsSubscribed];
Then in onClick, you can call setUserIsSubscribed(false), changing the hook's internal state, and re-rendering your component.