Как использовать lodash для управления несколькими кнопками с 1 дросселем? - PullRequest
0 голосов
/ 22 декабря 2018

Я бы хотел избежать совпадения и ограничить действие 1 в секунду.

Это потому, что событие onChange также запускает показ слайдов продолжительностью 1 с, а двойной запуск повреждает пользовательский интерфейс.

Я изначально начал с функции 4 debounces, но наконец-то дошел до:

import React from 'react';
import { css } from 'styled-components';
import PropTypes from 'prop-types';
import omit from 'lodash.omit';
import throttle from 'lodash.throttle';
import Img from '@bootstrap-styled/v4/lib/Img';

export default class ServicesAndSolutionImg extends React.PureComponent {
  static propTypes = {
    src: PropTypes.string.isRequired,
    alt: PropTypes.string.isRequired,
    onDigitalSolution: PropTypes.func.isRequired,
    onServices: PropTypes.func.isRequired,
    onHosting: PropTypes.func.isRequired,
    onAddons: PropTypes.func.isRequired,
  };

  state = {
    throttleFn: null,
  }

  componentWillMount() {
    this.setState({
      throttleFn: (e) => throttle(this.props[e.target.value], 1000, { leading: false, trailing: true })(),
    });
  }

  render() {
    const { src, alt } = omit(this.props, [
      'onDigitalSolution',
      'onServices',
      'onHosting',
      'onAddons',
    ]);

    return (
      <div css={css`position: relative`}>
        <Img fluid src={src} alt={alt} className="w-100 pt-3 pl-5 pr-5" />
        <div css={css`
          position: absolute;
          top: 0;
          right: 0;
          left: 0;
          right: 0;
          width: 100%;
          height: 100%;
        `}>
          <div css={css`
            position: relative;
            width: inherit;
            height: inherit;
            button {
              cursor: pointer;
              position: absolute;
              top: 23%;
              height: 51%;
              opacity: 0;
            }
            button:nth-child(1) {
              left: 15%;
              width: 16%;
            }
            button:nth-child(2) {
              left: 32%;
              width: 16%;
            }
            button:nth-child(3) {
              left: 48%;
              width: 16%;
            }
            button:nth-child(4) {
              left: 65%;
              width: 16%;
            }
          `}>
            <button onClick={this.state.throttleFn} value="onDigitalSolution" />
            <button onClick={this.state.throttleFn} value="onServices" />
            <button onClick={this.state.throttleFn} value="onHosting" />
            <button onClick={this.state.throttleFn} value="onAddons" />
          </div>
        </div>
      </div>
    );
  }
}

Ожидается

Без задержки, 1 клик в секунду, без параллелизма

Результат

Задержка в 1 секунду, до 4 одновременных действий.

Кто-нибудь знает, почему это не удается?Заранее спасибо,

1 Ответ

0 голосов
/ 22 декабря 2018

Дроссель - это функция, которая принимает функцию и возвращает дросселированную функцию.Дросселированная функция вызывает исходную функцию только один раз в окне x миллисекунд.

Многократный вызов throttle возвращает несколько удушенных функций, которые вы вызываете, и каждая из них является единственным вызовом в окне времени.

Чтобы исправить это, присвойте результат вызова throttleна обратный вызов свойства компонента и вызов этой функции при регистрации событий щелчка.

export default class ServicesAndSolutionImg extends React.PureComponent {
  static propTypes = {
    src: PropTypes.string.isRequired,
    alt: PropTypes.string.isRequired,
    onDigitalSolution: PropTypes.func.isRequired,
    onServices: PropTypes.func.isRequired,
    onHosting: PropTypes.func.isRequired,
    onAddons: PropTypes.func.isRequired,
  };

  // create the throttled function
  throttleFn = throttle((e) => this.props[e.target.value], 1000, { leading: false, trailing: true })

  render() {
     // no need to omit anything - you know what you want
    const { src, alt } = this.props;

    return (
      <div css={css`position: relative`}>
        <Img fluid src={src} alt={alt} className="w-100 pt-3 pl-5 pr-5" />
        <div css={css`
          position: absolute;
          top: 0;
          right: 0;
          left: 0;
          right: 0;
          width: 100%;
          height: 100%;
        `}>
          <div css={css`
            position: relative;
            width: inherit;
            height: inherit;
            button {
              cursor: pointer;
              position: absolute;
              top: 23%;
              height: 51%;
              opacity: 0;
            }
            button:nth-child(1) {
              left: 15%;
              width: 16%;
            }
            button:nth-child(2) {
              left: 32%;
              width: 16%;
            }
            button:nth-child(3) {
              left: 48%;
              width: 16%;
            }
            button:nth-child(4) {
              left: 65%;
              width: 16%;
            }
          `}>
            <button onClick={this.throttleFn} value="onDigitalSolution" />
            <button onClick={this.throttleFn} value="onServices" />
            <button onClick={this.throttleFn} value="onHosting" />
            <button onClick={this.throttleFn} value="onAddons" />
          </div>
        </div>
      </div>
    );
  }
}
...