Форум программистов, компьютерный форум, киберфорум
JavaScript: ReactJS
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126
1

Асинхронный useState

30.06.2022, 10:32. Показов 1910. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!!!
У меня вопрос в связи с тем что useState асинхронный.

Например я хочу задизаблить кнопку дождаться выполнения запросов и раздизеблить кнопку сделав редирект.
Хочу узнать можно ли как в коде делать или лучше по-другому т к нет гарантии установки стейта?

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const [isDisabled, setIsDisabled] = useState(false);
 
const fn = () => {
setIsDisabled(true);
try{
await sameReq1();
await sameReq2();
setIsDisabled(false); // Есть ли гарантия установки стейта для условия ниже?
 
!isDisabled ? redirect() : null;
}catch(e){
setIsDisabled(false)
}
 
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2022, 10:32
Ответы с готовыми решениями:

UseState и UseEffect
Добрый вечер. Такой вопрос. Есть UseState const = useState<boolean>(false); Который...

Изменение состояния useState
Есть такой код: import React, { useState } from 'react' const Task = () => { const =...

Проблема с асинхронностью useState React
Всем привет. Пишу программу погодную на реакте и столкнулся бедой с хуком useState. а именно то что...

useState поменять местами элементы массива
Здравствуйте!!! Подскажите, допустим есть массив cards, с помощь драг энд дропа я захватил элемент...

9
2984 / 1157 / 315
Регистрация: 14.03.2022
Сообщений: 2,822
30.06.2022, 11:27 2
Цитата Сообщение от riddlejs Посмотреть сообщение
Javascript
1
2
setIsDisabled(false); // Есть ли гарантия установки стейта для условия ниже?
!isDisabled ? redirect() : null;
После "старта" setIsDisabled(false) стейт сразу не поменяется...
Т.е. это
Javascript
1
!isDisabled ? redirect() : null;
Не сработает
1
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126
30.06.2022, 11:31  [ТС] 3
И что получается делать? какие варианты?
0
молодой
1641 / 905 / 291
Регистрация: 17.07.2021
Сообщений: 1,850
Записей в блоге: 12
30.06.2022, 12:30 4
Цитата Сообщение от riddlejs Посмотреть сообщение
какие варианты?
Отслеживать стейт через useEffect
1
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126
30.06.2022, 13:38  [ТС] 5
Т е так? юзэффект он запустит setIsDisabled(false); как только изменится isRequest и тогда условие в тернарнике точно сработает?

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const [isDisabled, setIsDisabled] = useState(false);
const [isRequest, setIsRequest] = useState(false);
 
useEffect(() => {
    if(isRequest){
        setIsDisabled(true);
    }else{
        setIsDisabled(false);
    }
 
}, [isRequest]);
 
const fn = () => {
setIsRequest(true);
try{
await sameReq1();
await sameReq2();
setIsRequest(false); // Есть ли гарантия установки стейта для условия ниже?
 
!isDisabled ? redirect() : null;
}catch(e){
setIsDisabled(false)
}
 
}
0
2984 / 1157 / 315
Регистрация: 14.03.2022
Сообщений: 2,822
30.06.2022, 14:17 6
Цитата Сообщение от riddlejs Посмотреть сообщение
Т е так?
Вариантов можно придумать несколько...
Например отслеживать isDisabled
- true можно запускать sameReq1() и sameReq2()...
- false делать redirect()
1
молодой
1641 / 905 / 291
Регистрация: 17.07.2021
Сообщений: 1,850
Записей в блоге: 12
30.06.2022, 14:21 7
Для начала объясните Ваш алгоритм, судя по этому нужно сделать ожидания выполнения запроса

Javascript
1
2
3
4
5
6
7
8
useEffect(() => {
    if(isRequest){
        setIsDisabled(true);
    }else{
        setIsDisabled(false);
    }
 
}, [isRequest]);

Но вот тут не совсем понятно

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
const fn = () => {
    setIsRequest(true);
    try {
        await sameReq1();
        await sameReq2();
        setIsRequest(false); // Есть ли гарантия установки стейта для условия ниже?
 
        !isDisabled ? redirect() : null;
    } catch (e) {
        setIsDisabled(false)
    }
 
}
setIsRequest(false) должно сделать isDisabled false и далее будет redirect

зачем если нет ни return ни присваивания
Javascript
1
!isDisabled ? redirect() : null;
Пока у меня сложилось впечатление что вы хотите сделать это

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import "./styles.css";
import React from "react";
const sameReq = () =>
  new Promise((resolve) => {
    setTimeout(() => resolve({ value: true }), 1000);
  });
 
export default function App() {
  const [isDisabled, setDisabled] = React.useState(false);
  const redirect = () => {};
  const onClick = async () => {
    setDisabled(true);
    await sameReq();
    setDisabled(false);
    redirect();
  };
  return (
    <div className="App">
      <button onClick={onClick} disabled={isDisabled}>
        Click
      </button>
    </div>
  );
}
Добавлено через 2 минуты
Да еще Вы забыли свою функцию сделать асинхронной, аwait в ней в лучшем случае не сработает
0
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126
30.06.2022, 14:34  [ТС] 8
Похоже я перегрелся и действительно зачем я к этому дизаблу и тернарнику прицепился.
Логика у меня такая я дизаблю кнопку пока идут запросы и если они успешны редирекчу, а если ошибка я снимаю дизабл и человек заново жмет кнопку.
0
молодой
1641 / 905 / 291
Регистрация: 17.07.2021
Сообщений: 1,850
Записей в блоге: 12
30.06.2022, 14:36 9
Лучший ответ Сообщение было отмечено riddlejs как решение

Решение

добавил try catch

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import "./styles.css";
import React from "react";
const sameReq = () =>
  new Promise((resolve) => {
    setTimeout(() => resolve({ value: true }), 1000);
  });
 
export default function App() {
  const [isDisabled, setDisabled] = React.useState(false);
  const redirect = () => {};
  const onClick = async () => {
    setDisabled(true);
    try{
      await sameReq();
    }
    catch(err){
      console.log(err.message)
    }
    setDisabled(false);
    redirect();
  };
  return (
    <div className="App">
      <button onClick={onClick} disabled={isDisabled}>
        Click
      </button>
    </div>
  );
}
1
1 / 1 / 0
Регистрация: 28.08.2022
Сообщений: 5
29.08.2022, 20:44 10
Можно с помощью реф

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export default function App() {
  const isLoadingRef = useRef(false)
 
  const onClick = async () => {
    if (!isLoadingRef.current) {
      isLoadingRef.current = true
      
      try {
        await sameReq()
        redirect()
      } catch (e) {
        console.log(e.message)
      } finally {
        isLoadingRef.current = false
      }
    }
  }
 
  return (
    <div className="App">
      <button onClick={onClick}>Click</button>
    </div>
  )
}
Но для лучшего UX, на кнопке желательно показать лоадер, потому без стейта тут врядли можно обойтись
0
29.08.2022, 20:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.08.2022, 20:44
Помогаю со студенческими работами здесь

useState initial state или useEffect
Здравствуйте!!! Я так понял что можно в useState передать функцию и стелать както так: ...

Асинхронный запрос
Запрашиваю данные с БД, потом экспортирую, и когда испортирую в другой файл, то приходит promise....

Типизация хука useState
Добрый вечер! я хочу передать значение isLoggedIn после установки значения черещ useState в...

Где можно посмотреть как имплементятся сетеры, возвращаемые useState()
Очень долго ломал голову как устроены сеттеры, в которые ты передаешь колбек. import...

Асинхронный system()
Подскажите метод асинхронного запуска внешних приложений. Поток не подходит, т.к. сложно...

Асинхронный вызов
Мы изучаем асинхронный вызов. Необходимо запустить(в моем случае 10 мячей) объекты в разных потоках...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru