Сохранение состояния активации / деактивации кнопки с помощью перехватчиков React - PullRequest
0 голосов
/ 09 июля 2020

Я пытался поддерживать состояние активации / деактивации кнопок при перезагрузке страницы в зависимости от статуса подписки пользователя (от менеджера pu sh). Идея состоит в том, что когда пользователь подписывается, кнопка подписки деактивирована, а состояние деактивированных кнопок сохраняется при перезагрузке страницы. Но с тем, что я пробовал до сих пор, после загрузки страницы состояние Toggle продолжает бесконечно переключаться между истиной и ложью ... Вот код, который у меня есть.

   // True enables notification button, False disables the button
    const [toggle, setToggle] = useState(true);

    // Updates users subscription status
    const [subStatus, setSubStatus] = useState(false);


    useEffect(() => {
        // Fetch subscription status from local storage
        setSubStatus(JSON.parse(localStorage.getItem('sub-status')));
         if(subStatus !== 'true'){
           setToggle(true);
         }else{
            setToggle(false);
         }

        //store subscription status to local storage
        localStorage.setItem('sub-status', JSON.stringify(subStatus));
    });

Функция, которая обрабатывает Click

function handleUserSubscription(e){
    e.preventDefault();
    navigator.serviceWorker.ready.then(subReg => {
        subReg.pushManager.getSubscription().then(sub => {
        if(!sub){ 
            Notification.requestPermission(response => {
                if(response === 'granted'){
                    subscribeUser();
                }else if(response === 'blocked'){
                    setSubStatus(false);
                    setToggle(false);
                }
            });
        }
        })
    })
}

// Register/Subscribe User to Push
function subscribeUser(){
    navigator.serviceWorker.getRegistration().then(reg => {
        reg.pushManager.subscribe({ 
            userVisibleOnly: true,
            applicationServerKey: urlB64ToUint8Array(
            'BCsA21O2LqhM36sqjcxSf08qk0KE5sz9GWUA_kK2o_ZIpuTc_LTzCu8zVg_2tAVvT988PP2it7ZodjdAinMM6A8'
            )
        })
        .then( sub => {         
            console.log('user has been subscribed!', JSON.stringify(sub));
            //updateServerWithSubscription(getSub)
            setSubStatus(true);
            setToggle(false); //disable notification once user is subscribed
            
        })
        .catch( err => {
                alert('Unable to subscribe User', err);
        })
    });
}

1 Ответ

1 голос
/ 09 июля 2020

Если вы не передадите массив зависимостей, то useEffect будет запускаться при каждом повторном рендеринге, что вызывает бесконечное l oop. если вы хотите, чтобы этот лог c вызывался только один раз при монтировании, вы должны сделать что-то вроде этого:

    useEffect(() => {
        // Fetch subscription status from local storage
        const status = JSON.parse(localStorage.getItem('sub-status'));
        
        setSubStatus(status);
        setToggle(Boolean(status !== 'true'));

        // (why do you need this?)
        // store subscription status to local storage
        // localStorage.setItem('sub-status', JSON.stringify(subStatus));
    }, []);
...