Comment re-rendre personnalisé crochet après un premier rendu

0

La question

J'ai personnalisé crochet nommé useIsUserSubscribed qui vérifie spécifique de l'utilisateur est abonné. Elle retourne true si l'utilisateur est abonné, et false si l'utilisateur n'est pas abonné...

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;

...J'ai un bouton à l'aide de ce crochet qui rend le texte conditionnel basé sur le booléen retourné à partir de 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>
  );
} 

Après onClick Je voudrais alors rendre à nouveau mon la useIsUserSubscribed crochet de Sorte que mon texte du bouton change. Cela peut-il être fait?

3

La meilleure réponse

2

vous ne pouvez pas utiliser useEffect dans votre crochet pour cela, essayez ceci :

crochet :

function useIsUserSubscribed() {
  const currentUserId = useSelector((state) => state.auth.user?.id);


  const checkUser = useCallback(async (publisherId, setUserIsSubscribed) => {
    if (!currentUserId || !publisherId) return;
      try {
        const res = await checkSubscription(publisherId);
        setUserIsSubscribed(true);
      } catch (err) {
        setUserIsSubscribed(false);
      }
    
  }, [currentUserId]);

  return {checkUser};
}

export default useIsUserSubscribed;

composant :

const SubscribeUnsubscribeBtn = ({profilePageUserId}) => {
    const [userIsSubscribed,setUserIsSubscribed]=useState(false);
    const { checkUser } = useIsUserSubscribed();

     useEffect(()=>{
        checkUser(profilePageUserId,setUserIsSubscribed)
     },[checkUser,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!!!!?
    checkUser(profilePageUserId,setUserIsSubscribed)
  }

  return (
    <button type="button" className="sub-edit-unsub-btn bsc-button" onClick={onClick}>
          {userIsSubscribed ? 'Subscribed' : 'Unsubscribed'}
    </button>
  );
} 

vous pouvez également ajouter un peu de chargement de l'état de votre crochet et de les retourner, alors vous pouvez vérifier si le processus est déjà fait ou pas

2021-11-24 03:03:13

J'ai l'intention de réutilisé cette logique dans d'autres parties si l'application. Quelle est la meilleure façon de faire ce réutilisable si le crochet n'est pas la meilleure approche?
Simone Anthony

@SimoneAnthony rien de mal avec des crochets et vous pouvez l'utiliser mais j'ai aussi remarqué que vous utilisez redux de sorte que vous pouvez utiliser redux-thunk actions trop
Mohammad
2

Ajouter un dependece sur useIsUserSubscribed de useEffect.

crochet :

function useIsUserSubscribed(publisherId) {
    const [userIsSubscribed, setUserIsSubscribed] = useState(null);
    const currentUserId = useSelector((state) => state.auth.user?.id);
    // add refresh dependece
    const refresh = useSelector((state) => state.auth.refresh);

    useEffect(() => {
        ...
    }, [publisherId, currentUserId, refresh]);
    ...
}

composant :

const onClick = async () => {
    ...
    // HOW CAN I RERENDER THE HOOK HERE!!!!?
    // when click, you can dispatch a refresh flag.
    dispatch(refreshSubState([]))
}

Exposer forceUpdate metheod.

crochet :

function useIsUserSubscribed(publisherId) {
    const [update, setUpdate] = useState({});
    const forceUpdate = () => {
        setUpdate({});
    }  

    return {userIsSubscribed, forceUpdate};
}

composant :

const {userIsSubscribed, forceUpdate} = useIsUserSubscribed(profilePageUserId);

const onClick = async () => {
    ...
    forceUpdate();
}
2021-11-24 02:56:11
0

Voici une autre solution par l'utilisateur @bitspook

SubscribeUnsubscribeBtn a une dépendance sur useIsUserSubscribedmais useIsUserSubscribed ne dépend pas de quelque chose de SubscribeUnsubscribeBtn. Au lieu de cela, useIsUserSubscribed est de garder un état local. Vous avez un couple de choix ici:

  1. Déplacer l'etat concernant demande si l'utilisateur est abonné ou pas de remonter d'un niveau, puisque vous utilisez Redux, peut-être dans Redux.
  2. Communiquer à useIsUserSubscribed que vous avez besoin de changer son état interne.

Pour 1)

  const [userIsSubscribed, setUserIsSubscribed] = useState(null);

se déplacer cet état de Redux les stocker et les utiliser avec useSelector.

Pour 2), retourner un tableau de valeur et de rappel à partir du crochet, au lieu de la valeur. Il vous permettra de communiquer de composant dans le crochet.

Dans useIsUserSubscribed,

  return [userIsSubscribed, setUserIsSubscribed];

Puis dans onClick, vous pouvez appeler setUserIsSubscribed(false), en changeant le crochet interne de l'état, et re-rendu de votre composant.

2021-11-24 03:37:35

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................