重置setTimeout函数以防止操作

时间:2019-04-16 14:32:25

标签: javascript css reactjs timeout settimeout

我可能在想这个错误的方式。因此,任何指导都将非常有用。

我有一个元素,然后当您单击打开多个单选按钮。点击其中一个单选按钮会触发setTimeout中的2300ms,这会向元素Frequency--closing添加一个类Frequency,当超时结束时,该元素会在CSS中触发动画,该组件将从DOM中删除。

我正在使用超时作为允许动画从DOM中删除之前的方法。

我的目标是当我单击一个单选按钮,然后单击另一个单选按钮,然后从计时器重置的DOM中删除组件之前,因此在第二次单击它之前,它会等待另一个2300ms从DOM中删除。

下面是使用状态指示通过onToggle()函数打开还是关闭元素的组件

const SavedSearchBox = ({ modifier, search, loading }) => {
  const [frequencyToggled, setFrequencyToggled] = useState(false);
  const [closeFrequency, setCloseFrequency] = useState(false);
  const timeoutRef = useRef(null);

  const onToggle = () => {
    if (frequencyToggled) {
      setCloseFrequency(true);
      timeoutRef.current = setTimeout(
        () => setFrequencyToggled(!frequencyToggled),
        2300
      );
    } else {
      setCloseFrequency(false);
      setFrequencyToggled(!frequencyToggled);
      clearTimeout(timeoutRef.current);
    }
  };

  useEffect(() => () => clearTimeout(timeoutRef.current), []);

  return (
    <div
      className={`SavedSearchBox ${modifier ? modifier : ""} ${
        loading && loading.status ? "SavedSearchBox--loading" : ""
      }`}
    >
      <div className="SavedSearchBox-footer">
        {frequencyToggled ? (
          <Frequency
            closeFrequency={closeFrequency}
            onChange={() => onToggle()}
          />
        ) : (
          <div onClick={() => onToggle()}>Click Here</div>
        )}
      </div>
    </div>
  );
};

还从子组件onToggle()中调用Frequency函数。该组件还包括结束动画的类Frequency--closing

const Frequency = props => {
  const [active, setActive] = useState(0);

  const inputs = [
    ["Instant Alerts", "Instant"],
    ["Twice Daily Alerts", "Twice"],
    ["Daily Alerts", "Daily"],
    ["Weekly Alerts", "Weekly"],
    ["No Email Alerts", "None"]
  ];
  return (
    <div
      className={`Frequency ${
        props.closeFrequency ? "Frequency--closing" : ""
      }`}
    >
      <div className="Frequency-list">
        {inputs.map(([text, value], i) => (
          <div key={i} className="Frequency-listItem">
            <label className="Frequency-listLabel">
              {text}
              <input
                type="radio"
                checked={value === inputs[active][1]}
                onChange={() => {
                  props.onChange();
                  setActive(i);
                }}
                value={value}
              />
              <span className="Frequency-listRadio" />
            </label>
          </div>
        ))}
      </div>
    </div>
  );
};

以下是可能引起此问题的动画

.Frequency-listItem {
  animation: enter $Frequency-duration $Frequency-easing backwards;
  transform: translateY(0%);
  transition: transform $Frequency-duration ease;
  display: flex;
  justify-content: left;
  align-items: center;

  @for $i from 1 through 6 {
    &:nth-of-type(#{$i}) {
      animation-delay: calc(#{$i} * #{$Frequency-delay});
    }
  }
}

.Frequency--closing .Frequency-listItem {
   animation: exit $Frequency-exitDuration $Frequency-easing both 1;
   transform: translateY(100%);
   transition: transform $Frequency-exitDuration ease;

   @for $i from 6*-1 through -1 {
      &:nth-of-type(#{abs($i)}) {
         animation-delay: calc(#{abs($i)} * #{$Frequency-exitDelay} + 2s);
      }
    }
 }

@keyframes enter {
  from {
      opacity: 0;
      padding: 0;
      margin: 0;
      max-height: 0;
      transform: scale(.7);
  }
}

@keyframes exit {
   from {
       opacity: 1;
       max-height: 100%;
       transform: scale(1);
   }
   to {
      opacity: 0;
      padding: 0;
      margin: 0;
      max-height: 0;
      transform: scale(.7);
  }
 }

如果您想测试一下,这里是CODESANBOX

任何帮助将不胜感激!

0 个答案:

没有答案