ClearInterval не очищает установленный интервал onMouseUp

При попытке создать событие кнопки onMouseDown функция должна запускаться по истечении заданного времени. Функция запускается onMouseDown и очищает интервал onMouseUp, но интервал продолжает работать после отпускания кнопки.

Это код в настоящее время. У меня есть глобальный интервал, и я установил его в функции посадки. Он должен сбрасываться в функции notPlanting, но это не так.

import React from "react";

function PlantDefuser() {
    var interval

    function planting() {
        interval = setInterval(() => {
            console.info("Defuser Planted")
        }, 1000)
    }

    function notPlanting() {
        console.info(interval)
        clearInterval(interval)
    }

    return (
        <button onMouseDown = {planting} onMouseUp = {notPlanting}>Press and Hold</button>
    )
}

export default PlantDefuser

Обратите внимание, что функция мыши вверх будет срабатывать только в том случае, если вы наведете курсор на кнопку, вы можете захотеть обнаружить мышь на уровне окна и очистить свой интервал, когда это срабатывает вместо этого.

IrkenInvader 29.11.2022 22:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
64
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это может помочь вам:

useRef позволяет нам хранить и обновлять данные в компоненте, не запуская повторный рендеринг. Теперь единственный повторный рендеринг происходит при обновлении реквизита.

Мы можем сохранить интервал в ref вот так

import { useRef } from "react";

const PlantDefuser = () => {
  const interval = useRef();

  function planting() {
    interval.current = setInterval(() => {
      console.info("Defuser Planted");
    }, 1000);
  }

  function notPlanting() {
    clearInterval(interval.current);
  }

  return (
    <button onMouseDown = {planting} onMouseUp = {notPlanting}>
      Press and Hold
    </button>
  );
}

export default PlantDefuser

Эй, это работает! Спасибо за ответы всем. Похоже, мне еще многое предстоит узнать о реакции.

SquidDOTjpeg 30.11.2022 19:42

Когда вы объявляете такие переменные в функциональном компоненте, они создаются при каждом рендеринге. Вы должны сохранить идентификатор интервала в таком состоянии:

import React, { useState } from "react";

const PlantDefuser = () => {
    const [plantingInterval, setPlantingInterval] = useState(null);

    const planting = () => {
        const plantingIntervalId = setInterval(() => {
            console.info("Defuser Planted");
        }, 1000);
        setPlantingInterval(plantingIntervalId);
    };

    const notPlanting = () => {
        clearInterval(plantingInterval);
        setPlantingInterval(null);
    };

    return (
        <button onMouseDown = {planting} onMouseUp = {notPlanting}>
            Press and Hold
        </button>
    );
};

export default PlantDefuser;

Вы также можете убедиться, что интервал очищается при размонтировании компонента.

Установка interval в состояние делает ненужный повторный рендеринг. лучшие варианты здесь с помощью крючка useRef

Martinez 29.11.2022 22:02

Вы правы, но это не имеет ни малейшего значения. Вы знаете, как мы обрабатываем, например, значения входных данных.

Angel Zlatanov 29.11.2022 22:11

Вы можете использовать хук useEffect с cleanup function для управления методом clearInterval.

как это :

function PlantDefuser() {
  const [run, setRun] = useState(false);

  useEffect(() => {
    if (run) {
      const countTimer = setInterval(() => {
        console.info("Defuser Planted");
      }, 1000);

      return () => {
        console.info(countTimer);
        clearInterval(countTimer);
      };
    }
  }, [run]);

  return (
    <button onMouseDown = {() => setRun(!run)} onMouseUp = {() => setRun(!run)}>
      Press and Hold
    </button>
  );
}

export default PlantDefuser;

Другие вопросы по теме