Cum de a re-face un cârlig personalizat după inițială render

0

Problema

Am personalizat cârlig nume useIsUserSubscribed care verifică pentru a vedea un anumit utilizator este abonat. Returnează true dacă utilizatorul este abonat și false dacă utilizatorul nu este abonat...

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;

...Am un buton, folosind acest cârlig care face textul condiționat bazează pe boolean întors de la 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>
  );
} 

După onClick Aș dori să rerender meu useIsUserSubscribed cârlig, Astfel încât textul buton comută. Se poate face asta?

3

Cel mai bun răspuns

2

nu puteți utiliza useEffect în cârlig pentru acest scop, încercați acest lucru :

cârlig :

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;

componenta :

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

puteți adăuga, de asemenea, unele de încărcare de stat în cârlig și să le întoarcă prea astfel încât să puteți verifica dacă procesul este deja făcut sau nu

2021-11-24 03:03:13

Am de gând să refolosite această logică în alte părți dacă aplicația. Ce este o modalitate mai bună de a face acest lucru reutilizabil în cazul în care cârligul nu este cea mai bună abordare?
Simone Anthony

@SimoneAnthony nimic în neregulă cu cârlige și îl puteți folosi, dar am observat, de asemenea, utilizați redux astfel încât să puteți utiliza redux-thunk acțiuni prea
Mohammad
2

Adauga un dependece pe useIsUserSubscribed e useEffect.

cârlig :

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

componenta :

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

Expune forceUpdate metheod.

cârlig :

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

    return {userIsSubscribed, forceUpdate};
}

componenta :

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

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

Aici este o altă soluție de utilizator @bitspook

SubscribeUnsubscribeBtn are o dependență pe useIsUserSubscribeddar useIsUserSubscribed nu depinde de nimic din SubscribeUnsubscribeBtn. În schimb, useIsUserSubscribed ține un stat locale. Aveți câteva opțiuni aici:

  1. Muta stat cu privire whetehr utilizatorul este abonat sau nu un nivel mai sus, din moment ce sunt utilizați Redux, probabil, în Redux.
  2. Să comunice useIsUserSubscribed de care aveți nevoie pentru a schimba starea sa internă.

Pentru 1)

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

muta acest stat să Redux magazin și să-l utilizați cu useSelector.

Pentru 2), returnează o matrice de valoare și apel de pe cârlig, în loc de doar valoarea. Aceasta vă va permite să comunice din componenta înapoi în cârlig.

În useIsUserSubscribed,

  return [userIsSubscribed, setUserIsSubscribed];

Apoi, în onClick, puteți apela setUserIsSubscribed(false), schimbarea cârlig de stat interne, și re-randare de componente.

2021-11-24 03:37:35

În alte limbi

Această pagină este în alte limbi

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