Как иметь условие в реагирующих крючках - PullRequest
1 голос
/ 27 сентября 2019

Я пытаюсь загрузить модальный загрузчик при загрузке страницы, если не нажата кнопка отмены.Предполагается, что функциональность должна работать так: когда страница загружается, подождите 2 секунды и покажите модал, если только не нажата кнопка отмены, в этом случае модал не должен отображаться, однако модал отображается независимо от нажатой кнопки отмены,

const Call = ({ t, i18n }) => {
  const [modalShow, setModalShow] = useState(false);
  const [cancelCall, setCancelCall] = useState(false);

  useEffect(() => {
     if (cancelCall) {
       return;
     } else {
       setTimeout(() => {
         setModalShow(true);
       }, 2000);
     }
  }, [setModalShow, cancelCall]);

  const handleCancelCall = e => {
    setCancelCall(true);
    console.log("cancel call pressed!");
  };

return (
    <Fragment>
      <CallModal show={modalShow} onHide={() => setModalShow(false)} />

    <button
            type="button"
            className="ml-4 btn btn-light"
            onClick={e => handleCancelCall()}
          >
            Cancel
          </button>
      </Fragment>
  );
};

Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 27 сентября 2019

Хотя ответ @ Rajesh работает, он вызывает 2 ненужных повторных рендеринга (вызов setTimer).Я бы порекомендовал вам просто следить за таймером, используя ref вместо

const [modalShow, setModalShow] = useState(false);
const modalTimer = useRef(null);

useEffect(() => {
  // the if (cancelCall) part in here was pointless 
  // because initial state is always false
  modalTimer.current = setTimeout(() => setModalShow(true), 2000);
}, []);

const handleCancelCall = e => {
  // on cancel, simply clear the timer
  modalTimer.current && clearTimeout(modalTimer.current);
};

Выше также удаляются некоторые избыточные код и состояние.

1 голос
/ 27 сентября 2019

Это связано с тем, что при загрузке страницы ваш cancelCall всегда будет ложным, и вы зарегистрируете событие тайм-аута.

Публикуйте, что пользователь нажимает кнопку, но зарегистрированное событие также необходимо удалить.,Попробуйте:

const Call = ({ t, i18n }) => {
  const [modalShow, setModalShow] = useState(false);
  const [cancelCall, setCancelCall] = useState(false);

  // Save the timer id in state
  const [timer, setTimer] = useState(null);

  useEffect(() => {
     if (cancelCall) {
       return;
     } else {
       const timer = setTimeout(() => {
         setModalShow(true);
       }, 2000);
       setTimer(timer)
     }
  }, [setModalShow, cancelCall]);

  const handleCancelCall = e => {
    setCancelCall(true);

    // On cancel, check if timer is not null. If not clear the timer from queue
    !!timer && window.clearTimeout(timer);
    setTimer(null)
    console.log("cancel call pressed!");
  };

return (
    <Fragment>
      <CallModal show={modalShow} onHide={() => setModalShow(false)} />

    <button
            type="button"
            className="ml-4 btn btn-light"
            onClick={e => handleCancelCall()}
          >
            Cancel
          </button>
      </Fragment>
  );
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...