Come re-rendering personalizzati uncinetto dopo iniziale di rendering

0

Domanda

Ho personalizzato il gancio di nome useIsUserSubscribed che controlla uno specifico utente è iscritto. Restituisce true se l'utente è iscritto e false se l'utente non è iscritto...

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;

...Ho un pulsante con questo gancio che rende il testo in modo condizionale in base boolean restituiti da 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>
  );
} 

Dopo onClick Vorrei eseguire il rendering di mio la useIsUserSubscribed il gancio in Modo che il mio testo del pulsante cambia. Questo può essere fatto?

3

Migliore risposta

2

non si possono usare useEffect nel vostro gancio per che scopo provare questo :

gancio :

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;

componente :

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>
  );
} 

è inoltre possibile aggiungere alcuni caricamento di stato nel vostro gancio e tornare troppo in modo da poter controllare se il processo è già stato fatto o non

2021-11-24 03:03:13

Ho intenzione di riutilizzare questa logica in altre parti se l'applicazione. Che cosa è un modo migliore per fare questo riutilizzabili se il gancio non è l'approccio migliore?
Simone Anthony

@SimoneAnthony niente di sbagliato con i ganci e la si può usare, ma ho anche notato che si utilizza redux modo è possibile utilizzare redux-thunk azioni troppo
Mohammad
2

Aggiungi un dependece su useIsUserSubscribed del useEffect.

gancio :

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]);
    ...
}

componente :

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

Esporre forceUpdate metheod.

gancio :

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

    return {userIsSubscribed, forceUpdate};
}

componente :

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

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

Qui è un'altra soluzione da utente @bitspook

SubscribeUnsubscribeBtn ha una dipendenza useIsUserSubscribedma useIsUserSubscribed non dipende da nulla da SubscribeUnsubscribeBtn. Invece, useIsUserSubscribed è talmente semplice mantenere aggiornati i locali dello stato. Avete un paio di scelte:

  1. Spostare lo stato riguardo whetehr utente sia iscritto o meno ad un livello superiore, dal momento che si sta utilizzando Redux, forse in Redux.
  2. Comunicare per useIsUserSubscribed che avete bisogno di cambiare il suo stato interno.

Per 1)

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

spostare questo stato di Redux conservare e utilizzare con useSelector.

Per 2), restituisce un array di valore e richiamata dal gancio, al posto del valore. Essa vi permetterà di comunicare componente indietro nel gancio.

In useIsUserSubscribed,

  return [userIsSubscribed, setUserIsSubscribed];

Quindi in onClickè possibile chiamare setUserIsSubscribed(false), cambiare il gancio stato interno e re-rendering componente.

2021-11-24 03:37:35

In altre lingue

Questa pagina è in altre lingue

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