防止事件连续执行React

时间:2020-03-25 18:37:56

标签: javascript reactjs highcharts react-hooks

我有一个具有此状态的父组件,它是一个对象,属性之一是一个名为onScrollbarSelection的函数,该函数会发布axios帖子。所有这些都将传递给子组件。

子组件使用Highcharts的API,API的属性之一(afterSetExtremes)使用父组件(props)的onScrollbarSelection函数。问题在于afterSetExtremes可以触发很多连续的时间,这使得onScrollbarSelection函数也可以执行很多连续的时间,并且发出很多axios帖子,从而导致浏览器崩溃。

我曾尝试在post呼叫上设置超时,但没有成功,它仍然使axios多次发布。如何防止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 个答案:

答案 0 :(得分:2)

您应使用具有去抖动效果的功能。

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}
    />
  );
};

答案 1 :(得分:0)

您还可以尝试在 onScrollbarSelection 功能中实现 setTimeout clearInterval 。就像下面的演示一样,所需功能仅触发一次:

演示:https://jsfiddle.net/BlackLabel/c0e9L6nf/

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

编辑:

以下是使用React复制上述建议的演示:https://stackblitz.com/edit/react-adeke4?file=index.js

相关问题