Предотвращение события от выполнения последовательных раз - PullRequest
2 голосов
/ 25 марта 2020

У меня есть этот родительский компонент, который имеет это состояние, которое является объектом, одним из свойств является функция с именем onScrollbarSelection, которая создает топор ios post. Все это будет передано дочернему компоненту.

Дочерний компонент использует API из Highcharts, одно из свойств (afterSetExtremes) API использует функцию onScrollbarSelection из родительского (props). Проблема в том, что afterSetExtremes может запускать много раз подряд, что заставляет функцию onScrollbarSelection также выполнять много раз подряд и делает много постов ax ios, вызывая сбой браузера.

попытался поставить тайм-аут на пост-вызов, но не сработал, он все еще вызывает, заставляет топор ios публиковать много раз. Как я могу предотвратить выполнение onScrollbarSelection (или события afterSetExtremes) много раз подряд?

const Parent = () => {
    const [state,setState] = useState({
        onScrollbarSelection: (e) => {
            var min = new Date(e.min);
            var max = new Date(e.max);
            var minDate = min.getFullYear() + '-' + (min.getMonth() + 1) + '-' + min.getDate();
            var maxDate = max.getFullYear() + '-' + (max.getMonth() + 1) + '-' + max.getDate();
            async function postData() {
                axios.post('url',{
                    start_date: minDate,
                    end_date: maxDate,
                });
            }
            setTimeout(postData(),3000);
        }
    });

    useEffect( () => {
        async function fetchData() {
            var res = await axios.get(url);
            setState({
                ...state,
                data: res.data,
            });
        }
        fetchData();
    },[]);



   return(
        <div>
             <Child config={state}/>
        </div>
   )

};

const Child = (props) => {
    const state = {
        xAxis:{
            events: {
                afterSetExtremes: (e) => { //this triggers a lot of consecutive times
                    props.config.onScrollbarSelection(e);
                }
            }

        }, 
    };

    return (
        <div>
            <HighchartsReact highcharts={Highcharts} constructorType={'stockChart'} options={state} />
        </div>
    );
}

Ответы [ 2 ]

2 голосов
/ 25 марта 2020

Вы должны использовать функцию с эффектом debounce .

const Parent = () => {
  const [data, setDate] = React.useState(); 
  const [state, setState] = React.useState([]);
  
  const afterSetExtremes = React.useCallback(({ min, max }) => {
    setState([min, max]);
  }, []);
  /* create option for HighchartsReact */
  const option = React.useMemo(() => ({
    xAxis: {
      events: {
        afterSetExtremes,
      },
    },
  }), [afterSetExtremes]);
  /* get data from url end set it to data state */
  useEffect( () => {
    axios.get('url')
      .then((res) => {
        setDate(res.data);
      })
  },[]);
  /* do post if state changed, works with debounce 250ms */
  useEffect(() => {
    const handler = setTimeout(() => {
      const [minDate, maxDate] = state.map((value) => {
        const d = new Date(value);
        return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
      });
      
      axios.post('url', { start_date: minDate, end_date: maxDate })
        .then((res) => {})
        .catch((error) => {});
    }, 250);
    
    return () => {
      /* if state changed in 250ms
       * clearTimeout remove handler
       * and axios.post does not call.
       */
      clearTimeout(handler);
    };
  }, [state]);

  return (
    <HighchartsReact
      highcharts={Highcharts}
      constructorType='stockChart'
      options={option}
    />
  );
};
0 голосов
/ 26 марта 2020

Вы также можете попробовать реализовать setTimeout и clearInterval в вашей onScrollbarSelection функциональности. Как и в демонстрации ниже, где требуемые функции запускаются только один раз:

Демо: https://jsfiddle.net/BlackLabel/c0e9L6nf/

  xAxis: {
    events: {
      afterSetExtremes() {
        myStopFunction()
        myFunction()
      }
    }
  }

РЕДАКТИРОВАТЬ:

Вот демонстрация с воспроизведением вышеуказанного предложения с использованием React: https://stackblitz.com/edit/react-adeke4?file=index.js

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