effectussoftware / react-custom-roulette

Repository for the react-custom-roulette library
MIT License
312 stars 112 forks source link

Not sure why fe[n] is undefined is raised for my wheel implementation #163

Closed itsMGA closed 2 months ago

itsMGA commented 2 months ago
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import axiosInstance from '../../../axiosConfig';
import './wheel.css';
import { getUserInfo } from '../../../user_info';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
import MemoizedWheel from './MemoizedWheel';
import { useUser } from '../../../UserContext';
import WheelAdmin from './WheelAdmin';

const LoadingAnimation = () => (
    <div className="loading-animation">
        <div className="spinner"></div>
        <p>Loading...</p>
    </div>
);

const ButtonLoadingAnimation = () => (
    <div className="button-loading-animation">
        <div className="dot-pulse"></div>
    </div>
);

export default function WheelComponent({
    availablePrizes,
    hasPlayedEnough,
    isLoading,
    error,
    onSuccessfulSpin
}) {
    const { user } = useUser();
    const [prizes, setPrizes] = useState(availablePrizes);
    const [mustSpin, setMustSpin] = useState(false);
    const [prizeNumber, setPrizeNumber] = useState(0);
    const [showPrize, setShowPrize] = useState(false);
    const [apiMessage, setApiMessage] = useState('');
    const [awards, setAwards] = useState([]);
    const [isAwardsTableVisible, setIsAwardsTableVisible] = useState(false);
    const [awardsError, setAwardsError] = useState(null);
    const [isTableLoading, setIsTableLoading] = useState(false);
    const [showFireworks, setShowFireworks] = useState(false);
    const [availableSpins, setAvailableSpins] = useState(0);
    const [cooldownTime, setCooldownTime] = useState(0);
    const [countdown, setCountdown] = useState(null);
    const [spinError, setSpinError] = useState(null);
    const awardsRef = useRef(null);
    const isSpinning = useRef(false);

    const imageSizeMultiplier = 0.37;
    const wheelSizeMultiplier = 1.3;
    const imageOrientation = 'portrait';

    const tableRowVariants = {
        hidden: { opacity: 0, y: 20 },
        visible: (i) => ({
            opacity: 1,
            y: 0,
            transition: {
                delay: i * 0.1,
                duration: 0.3,
            },
        }),
        exit: { opacity: 0, y: -20, transition: { duration: 0.2 } },
    };

    const sortedAwards = useMemo(() => {
        // console.log('Sorting awards:', awards);
        return [...awards].sort((a, b) => new Date(b.given_time) - new Date(a.given_time));
    }, [awards]);

    useEffect(() => {
        const checkSpinData = async () => {
            const storedSpins = localStorage.getItem('availableSpins');

            if (storedSpins) {
                const spins = parseInt(storedSpins, 10);
                if (spins > 0) {
                    setAvailableSpins(spins);
                    setCooldownTime(0);
                    setCountdown(null);
                    localStorage.removeItem('wheelCooldownEndTime');
                } else {
                    await fetchSpinData();
                }
            } else {
                await fetchSpinData();
            }
        };

        const fetchSpinData = async () => {
            try {
                const ip = await fetch('https://api.ipify.org?format=json')
                    .then(response => response.json())
                    .then(data => data.ip);
                const spinsResponse = await axiosInstance.get(`/wheel-awards/user-spin/?ip=${ip}`);
                const { number_of_spins, last_spin_date, spin_refresh } = spinsResponse.data;

                setAvailableSpins(number_of_spins);
                localStorage.setItem('availableSpins', number_of_spins.toString());

                if (number_of_spins > 0) {
                    setCooldownTime(0);
                    setCountdown(null);
                    localStorage.removeItem('wheelCooldownEndTime');
                } else {
                    const lastSpinTime = new Date(last_spin_date).getTime();
                    const currentTime = Date.now();
                    const elapsedTime = (currentTime - lastSpinTime) / 1000;
                    const remainingCooldown = Math.max(0, spin_refresh - elapsedTime);

                    setCooldownTime(Math.ceil(remainingCooldown));
                    const endTime = Date.now() + remainingCooldown * 1000;
                    localStorage.setItem('wheelCooldownEndTime', endTime.toString());
                }
            } catch (error) {
                console.error('Error fetching spin data:', error);
            }
        };

        checkSpinData();
    }, []);

    useEffect(() => {
        let timer;
        if (showPrize) {
            timer = setTimeout(() => {
                setShowPrize(false);
            }, 122250);
        }
        return () => clearTimeout(timer);
    }, [showPrize]);

    // useEffect(() => {
    //     console.log('Awards state updated:', awards);
    // }, [awards]);

    useEffect(() => {
        let intervalId;

        const updateCountdown = () => {
            const endTime = parseInt(localStorage.getItem('wheelCooldownEndTime'), 10);
            if (!endTime) return;

            const remaining = Math.max(0, Math.ceil((endTime - Date.now()) / 1000));
            setCountdown(remaining);

            if (remaining === 0) {
                localStorage.removeItem('wheelCooldownEndTime');
                setAvailableSpins(1);
                localStorage.setItem('availableSpins', '1');
            }
        };

        if (availableSpins === 0 && cooldownTime > 0) {
            updateCountdown();
            intervalId = setInterval(updateCountdown, 1000);
        }

        return () => {
            if (intervalId) clearInterval(intervalId);
        };
    }, [availableSpins, cooldownTime]);

    const fetchAwards = useCallback(async () => {
        setIsTableLoading(true);
        try {
            const response = await axiosInstance.get('/wheel-awards/awards-list/');
            // console.log('Awards API response:', response.data);
            setAwards(response.data);
            setAwardsError(null);
        } catch (error) {
            console.error('Error fetching awards:', error);
            setAwardsError('Failed to load awards data. Please try again later.');
        } finally {
            setIsTableLoading(false);
        }
    }, []);

    const handleSpinClick = useCallback(async () => {
        if (isSpinning.current || availableSpins === 0 || !hasPlayedEnough) return;
        isSpinning.current = true;
        setSpinError(null);
        try {
            const userInfo = getUserInfo();
            const response = await axiosInstance.post('/wheel-awards/get-prize/', {
                ip_address: userInfo.ip,
                country: userInfo.country,
                unique_id: userInfo.unque_id
            });
            const { prizeNumber, selectedPrize } = response.data;
            setPrizeNumber(prizeNumber);
            setMustSpin(true);
            setShowPrize(false);

            const newSpinCount = availableSpins - 1;
            setAvailableSpins(newSpinCount);
            localStorage.setItem('availableSpins', newSpinCount.toString());

            if (newSpinCount === 0) {
                const ip = await fetch('https://api.ipify.org?format=json')
                    .then(response => response.json())
                    .then(data => data.ip);
                const spinsResponse = await axiosInstance.get(`/wheel-awards/user-spin/?ip=${ip}`);
                const { last_spin_date, spin_refresh } = spinsResponse.data;

                const lastSpinTime = new Date(last_spin_date).getTime();
                const currentTime = Date.now();
                const elapsedTime = (currentTime - lastSpinTime) / 1000;
                const remainingCooldown = Math.max(0, spin_refresh - elapsedTime);

                setCooldownTime(Math.ceil(remainingCooldown));
                const endTime = Date.now() + remainingCooldown * 1000;
                localStorage.setItem('wheelCooldownEndTime', endTime.toString());
            }

            onSuccessfulSpin();
        } catch (error) {
            console.error('Error fetching prize:', error);
            setSpinError("Something went wrong while spinning. Please contact an administrator or try again.");
            setMustSpin(false);
        } finally {
            isSpinning.current = false;
        }
    }, [availableSpins, hasPlayedEnough, onSuccessfulSpin]);

    const dataWithImageSize = useMemo(() => prizes.map((item) => ({
        ...item,
        image: {
            ...item.image_uri,
            sizeMultiplier: imageSizeMultiplier,
            landscape: imageOrientation === 'landscape',
        },
    })), [prizes, imageSizeMultiplier, imageOrientation]);

    const toggleAwardsTable = useCallback(() => {
        setIsAwardsTableVisible(!isAwardsTableVisible);
        if (!isAwardsTableVisible && awards.length === 0) {
            fetchAwards();
        }
        if (!isAwardsTableVisible) {
            setTimeout(() => {
                awardsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }, 100);
        }
    }, [isAwardsTableVisible, awards.length, fetchAwards]);

    const handleStopSpinning = useCallback(() => {
        isSpinning.current = false;
        setMustSpin(false);
        setShowPrize(true);
        setShowFireworks(true);
        fetchAwards();
        setTimeout(() => {
            setShowFireworks(false);
        }, 2000);
    }, [fetchAwards]);

    const formatTime = (totalSeconds) => {
        const hours = Math.floor(totalSeconds / 3600);
        const minutes = Math.floor((totalSeconds % 3600) / 60);
        const seconds = totalSeconds % 60;

        const parts = [];
        if (hours > 0) parts.push(`${hours}h`);
        if (minutes > 0 || hours > 0) parts.push(`${minutes}m`);
        parts.push(`${seconds}s`);

        return parts.join(' ');
    };

    if (error) {
        return <div className="error-message">{error}</div>;
    }

    if (isLoading || prizes.length === 0) {
        return <LoadingAnimation />;
    }

    return (
        <>
            <h1 className="wheel-title">Wheel of fortune</h1>
            <div className='wheel-main-container'>
                <div className='wheel' style={{ transform: `scale(${wheelSizeMultiplier})` }}>
                    <MemoizedWheel
                        mustSpin={mustSpin}
                        prizeNumber={prizeNumber}
                        data={dataWithImageSize}
                        onStopSpinning={handleStopSpinning}
                    />
                    <AnimatePresence>
                        {showPrize ? (
                            <div className="prize-display-container">
                                <motion.div
                                    key="prize-display"
                                    className="prize-display"
                                    initial={{ opacity: 0 }}
                                    animate={{ opacity: 1 }}
                                    exit={{ opacity: 0 }}
                                    transition={{ duration: 0.5 }}
                                >
                                    <svg
                                        xmlns="http://www.w3.org/2000/svg"
                                        width="24"
                                        height="24"
                                        viewBox="0 0 24 24"
                                        fill="none"
                                        stroke="green"
                                        strokeWidth="2"
                                        strokeLinecap="round"
                                        strokeLinejoin="round"
                                        className="circle-border"
                                    >
                                        <circle cx="12" cy="12" r="10"></circle>
                                    </svg>
                                    <img className='prize-img' src={prizes[prizeNumber].image_uri.uri} alt={`Prize ${prizeNumber + 1}`} />
                                    <p className='prize-text'>{prizes[prizeNumber].text}</p>
                                </motion.div>
                            </div>
                        ) : (
                            <motion.div
                                key="prize-display-none"
                                className="prize-display-none"
                                initial={{ opacity: 0 }}
                                animate={{ opacity: 1 }}
                                exit={{ opacity: 0 }}
                                transition={{ duration: 0.5 }}
                            >
                                <svg
                                    xmlns="http://www.w3.org/2000/svg"
                                    width="24"
                                    height="24"
                                    viewBox="0 0 24 24"
                                    fill="none"
                                    stroke="currentColor"
                                    strokeWidth="2"
                                    strokeLinecap="round"
                                    strokeLinejoin="round"
                                    className="feather feather-help-circle"
                                >
                                    <circle cx="12" cy="12" r="10"></circle>
                                    <path d="M9.09 9a3 3 0 1 1 5.82 1c0 2-3 3-3 4.5"></path>
                                    <line x1="12" y1="17" x2="12" y2="17"></line>
                                </svg>
                            </motion.div>
                        )}
                    </AnimatePresence>
                </div>
                <div className="spin-button-container">
                    {apiMessage === "Only two accounts allowed per network" && (
                        <div className="error-container">
                            <p className="dup-acc-err-msg">You have already spun the wheel on another account!</p>
                        </div>
                    )}
                    <button
                        className='spin-button'
                        onClick={handleSpinClick}
                        disabled={isSpinning.current || availableSpins === 0 || !hasPlayedEnough}
                    >
                        {isSpinning.current ? 'Spinning...' :
                            availableSpins > 0 ? `SPIN (${availableSpins} spins left)` :
                                countdown !== null ? `Next spin in ${formatTime(countdown)}` :
                                    'SPIN'}
                    </button>
                    {!hasPlayedEnough && (
                        <p className="play-time-message">You have to play at least 30 minutes to access the wheel.</p>
                    )}
                    {spinError && (
                        <div className="spin-error-message">
                            {spinError}
                        </div>
                    )}
                </div>
                {user && user.isAdmin && <WheelAdmin prizes={prizes} setPrizes={setPrizes} />}
                <div className="awards-table-container" ref={awardsRef}>
                    <h2 className="awards-title" onClick={toggleAwardsTable}>
                        Your Awards
                        <span className="arrow-container">
                            <FontAwesomeIcon
                                icon={faChevronDown}
                                className={`arrow ${isAwardsTableVisible ? 'up' : ''}`}
                            />
                        </span>
                    </h2>
                    <AnimatePresence>
                        {isAwardsTableVisible && (
                            <motion.div
                                initial={{ height: 0, opacity: 0 }}
                                animate={{ height: 'auto', opacity: 1 }}
                                exit={{ height: 0, opacity: 0 }}
                                transition={{ duration: 0.3 }}
                            >
                                {isTableLoading ? (
                                    <LoadingAnimation />
                                ) : awardsError ? (
                                    <div className="awards-error">{awardsError}</div>
                                ) : awards.length > 0 ? (
                                    <table className="awards-table">
                                        <thead>
                                            <tr>
                                                <th>Prize</th>
                                                <th>Item Name</th>
                                                <th>Count</th>
                                                <th>Date</th>
                                                <th>Assigned in game</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <AnimatePresence>
                                                {sortedAwards.map((award, index) => (
                                                    <motion.tr
                                                        key={index}
                                                        custom={index}
                                                        variants={tableRowVariants}
                                                        initial="hidden"
                                                        animate="visible"
                                                        exit="exit"
                                                    >
                                                        <td className='prize-image' data-label="Image">
                                                            <img src={award.prize_image} alt={award.prize_text} className="award-image" />
                                                        </td>
                                                        <td data-label="Prize Text">{award.prize_text}</td>
                                                        <td data-label="Count">{award.count}</td>
                                                        <td data-label="Date">{new Date(award.given_time).toLocaleString()}</td>
                                                        <td data-label="Is Item Given">{award.is_item_given ? 'Yes' : 'No'}</td>
                                                    </motion.tr>
                                                ))}
                                            </AnimatePresence>
                                        </tbody>
                                    </table>
                                ) : (
                                    <p>No awards to display.</p>
                                )}
                            </motion.div>
                        )}
                    </AnimatePresence>
                </div>
            </div>
            {showFireworks && (
                <div className="fireworks-container">
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                    <div className="firework"></div>
                </div>
            )}
        </>
    );
}
import React, { memo } from 'react';
import { Wheel } from 'react-custom-roulette';

const MemoizedWheel = memo(({ mustSpin, prizeNumber, data, onStopSpinning }) => (
    console.log('MemoizedWheel: prizeNumber', prizeNumber),
    console.log("data", data),
    <Wheel
        mustStartSpinning={mustSpin}
        prizeNumber={prizeNumber}
        data={data}
        onStopSpinning={onStopSpinning}
        outerBorderColor="transparent"
        outerBorderWidth={10}
        innerRadius={40}
        innerBorderColor="#30261a"
        innerBorderWidth={0}
        radiusLineColor="#30261a"
        radiusLineWidth={2}
        spinDuration={0.8}
        fontFamily="Arial"
        fontSize={16}
        perpendicularText={false}
        textDistance={75}
        pointerProps={{
            style: {
                position: 'absolute',
                transform: 'translateX(-75%) translateY(89%) rotate(225deg)',
                width: '0',
                height: '0',
                borderLeft: '20px solid transparent',
                borderRight: '20px solid transparent',
                borderBottom: '40px solid #f0ad4e',
            },
        }}
    />
));

export default MemoizedWheel;

dosen't really make sense, what is not aight?

Data array was len 29 for ex and prize Number 12, and when wheel is done spinning aka "picking a prize" it throws that err

Thing is, the error is returned at the end of the spin

itsMGA commented 2 months ago

Uncaught runtime errors: ERROR fe[n] is undefined ./node_modules/react-custom-roulette/dist/bundle.js/</</O/<@http://localhost:3000/main.a9bcc859b52a7f215f6c.hot-update.js:2475:32 commitHookEffectListMount@http://localhost:3000/static/js/bundle.js:42514:30 commitPassiveMountOnFiber@http://localhost:3000/static/js/bundle.js:44007:42 commitPassiveMountEffects_complete@http://localhost:3000/static/js/bundle.js:43979:38 commitPassiveMountEffects_begin@http://localhost:3000/static/js/bundle.js:43969:45 commitPassiveMountEffects@http://localhost:3000/static/js/bundle.js:43959:38 flushPassiveEffectsImpl@http://localhost:3000/static/js/bundle.js:45842:32 flushPassiveEffects@http://localhost:3000/static/js/bundle.js:45795:18 ./node_modules/react-dom/cjs/react-dom.development.js/commitRootImpl/<@http://localhost:3000/static/js/bundle.js:45610:13 workLoop@http://localhost:3000/static/js/bundle.js:53046:46 flushWork@http://localhost:3000/static/js/bundle.js:53024:18 performWorkUntilDeadline@http://localhost:3000/static/js/bundle.js:53261:25 EventHandlerNonNull./node_modules/scheduler/cjs/scheduler.development.js/<@http://localhost:3000/static/js/bundle.js:53297:7 ./node_modules/scheduler/cjs/scheduler.development.js@http://localhost:3000/static/js/bundle.js:53347:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require__@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/scheduler/index.js@http://localhost:3000/static/js/bundle.js:53362:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/cjs/react-dom.development.js/<@http://localhost:3000/static/js/bundle.js:22516:40 ./node_modules/react-dom/cjs/react-dom.development.js@http://localhost:3000/static/js/bundle.js:48229:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/index.js@http://localhost:3000/static/js/bundle.js:48300:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 __webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/client.js@http://localhost:3000/static/js/bundle.js:48243:28 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./src/index.js@http://localhost:3000/static/js/bundle.js:6093:93 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 @http://localhost:3000/static/js/bundle.js:123707:56 @http://localhost:3000/static/js/bundle.js:123709:12 ERROR fe[n] is undefined ./node_modules/react-custom-roulette/dist/bundle.js/</</O/<@http://localhost:3000/main.a9bcc859b52a7f215f6c.hot-update.js:2475:32 commitHookEffectListMount@http://localhost:3000/static/js/bundle.js:42514:30 commitPassiveMountOnFiber@http://localhost:3000/static/js/bundle.js:44007:42 commitPassiveMountEffects_complete@http://localhost:3000/static/js/bundle.js:43979:38 commitPassiveMountEffects_begin@http://localhost:3000/static/js/bundle.js:43969:45 commitPassiveMountEffects@http://localhost:3000/static/js/bundle.js:43959:38 flushPassiveEffectsImpl@http://localhost:3000/static/js/bundle.js:45842:32 flushPassiveEffects@http://localhost:3000/static/js/bundle.js:45795:18 ./node_modules/react-dom/cjs/react-dom.development.js/commitRootImpl/<@http://localhost:3000/static/js/bundle.js:45610:13 workLoop@http://localhost:3000/static/js/bundle.js:53046:46 flushWork@http://localhost:3000/static/js/bundle.js:53024:18 performWorkUntilDeadline@http://localhost:3000/static/js/bundle.js:53261:25 EventHandlerNonNull./node_modules/scheduler/cjs/scheduler.development.js/<@http://localhost:3000/static/js/bundle.js:53297:7 ./node_modules/scheduler/cjs/scheduler.development.js@http://localhost:3000/static/js/bundle.js:53347:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require__@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/scheduler/index.js@http://localhost:3000/static/js/bundle.js:53362:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/cjs/react-dom.development.js/<@http://localhost:3000/static/js/bundle.js:22516:40 ./node_modules/react-dom/cjs/react-dom.development.js@http://localhost:3000/static/js/bundle.js:48229:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/index.js@http://localhost:3000/static/js/bundle.js:48300:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 __webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/client.js@http://localhost:3000/static/js/bundle.js:48243:28 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./src/index.js@http://localhost:3000/static/js/bundle.js:6093:93 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 @http://localhost:3000/static/js/bundle.js:123707:56 @http://localhost:3000/static/js/bundle.js:123709:12 ERROR fe[n] is undefined ./node_modules/react-custom-roulette/dist/bundle.js/</</O/<@http://localhost:3000/main.a9bcc859b52a7f215f6c.hot-update.js:2475:32 commitHookEffectListMount@http://localhost:3000/static/js/bundle.js:42514:30 commitPassiveMountOnFiber@http://localhost:3000/static/js/bundle.js:44007:42 commitPassiveMountEffects_complete@http://localhost:3000/static/js/bundle.js:43979:38 commitPassiveMountEffects_begin@http://localhost:3000/static/js/bundle.js:43969:45 commitPassiveMountEffects@http://localhost:3000/static/js/bundle.js:43959:38 flushPassiveEffectsImpl@http://localhost:3000/static/js/bundle.js:45842:32 flushPassiveEffects@http://localhost:3000/static/js/bundle.js:45795:18 ./node_modules/react-dom/cjs/react-dom.development.js/commitRootImpl/<@http://localhost:3000/static/js/bundle.js:45610:13 workLoop@http://localhost:3000/static/js/bundle.js:53046:46 flushWork@http://localhost:3000/static/js/bundle.js:53024:18 performWorkUntilDeadline@http://localhost:3000/static/js/bundle.js:53261:25 EventHandlerNonNull*./node_modules/scheduler/cjs/scheduler.development.js/<@http://localhost:3000/static/js/bundle.js:53297:7 ./node_modules/scheduler/cjs/scheduler.development.js@http://localhost:3000/static/js/bundle.js:53347:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require__@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/scheduler/index.js@http://localhost:3000/static/js/bundle.js:53362:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/cjs/react-dom.development.js/<@http://localhost:3000/static/js/bundle.js:22516:40 ./node_modules/react-dom/cjs/react-dom.development.js@http://localhost:3000/static/js/bundle.js:48229:5 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/index.js@http://localhost:3000/static/js/bundle.js:48300:20 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 __webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./node_modules/react-dom/client.js@http://localhost:3000/static/js/bundle.js:48243:28 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 fn@http://localhost:3000/static/js/bundle.js:122783:21 ./src/index.js@http://localhost:3000/static/js/bundle.js:6093:93 options.factory@http://localhost:3000/static/js/bundle.js:123125:31 webpack_require@http://localhost:3000/static/js/bundle.js:122576:32 @http://localhost:3000/static/js/bundle.js:123707:56 @http://localhost:3000/static/js/bundle.js:123709:12

itsMGA commented 2 months ago

Seems to have something to do with these states that I update at the end of the spin const handleStopSpinning = useCallback(() => {