@flexpc

Блокировка кнопки на время выполнения функции?

Была проблема, придумал такое решение:
const [desable, setDesable] = React.useState(false);

function tap() {
    setDesable(true);
    //какой то код
    setDesable(false);

  return (
    <div className="App">
    <button disabled={desable} onClick={tap}>Считать</button>
    </div>


Вроде бы кнопка блокируется, но при этом если сделать двойной клик, то функция все равно выполниться два раза.
Как исправить?
  • Вопрос задан
  • 97 просмотров
Пригласить эксперта
Ответы на вопрос 2
@ivan_ivanov_ivanych
Реакт имеет свойство оптимизировать изменение состояния компонента в одной функции, для того, чтобы избегать лишних перерендеров компонента. Обойти это можно можно с помощью асинхронных функций.
async function tap() {
    setDesable(true);
    //какой то код
     await new Promise((resolve) => setTimeout(resolve, 1000));
    setDesable(false);
}

В этой функции сначала выполняется первая функция изменения состояние setDisable(true), далее ожидание выполнения промиса, во время которого происходил перерендер. И далее, спустя 1000 мс, вызывается setDisable(false)
Ответ написан
muscimolus
@muscimolus
Не знаю, в чём у тебя проблема, но такой-же код отрабатывает нормально, причём в любых вариантах:

// fetch
import React, { useState } from 'react'

export const Button = () => {
    const [ disabled, setDisabled ] = useState(false)
    const [ data, setData ] = useState(null)
    const handleClick = () => {
        console.log('fetch')
        setDisabled(true)
        fetch('https://fakestoreapi.com/products').then(r => r.json()).then(data => {
            console.log('fetched', data)
            setDisabled(false)
            setData(data)
        })
    }
    return (
        <>
            <button type="button" onClick={ handleClick } disabled={ disabled }>
                Fetch
            </button>
            { data ? (
                <pre>{ JSON.stringify(data, null, 2) }</pre>
            ) : null }
        </>
    )
}

// timeout
import React, { useState } from 'react'

export const Button = () => {
    const [ disabled, setDisabled ] = useState(false)
    const handleClick = () => {
        console.log('timeout')
        setDisabled(true)
        setTimeout(() => {
            console.log('timed out')
            setDisabled(false)
        }, 2000)
    }
    return (
        <button type="button" onClick={ handleClick } disabled={ disabled }>
            Timeout
        </button>
    )
}


P.S. А вообще, не могу понять, почему код скинут кусками. Отправь вообще весь компонент, просто скопируй всё и поменяй в вопросе самом предыдущий код. Может у тебя ещё в чём-то дело.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы