+-
防止连续执行React事件

我有一个具有此状态的父组件,它是一个对象,属性之一是一个称为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>
    );
}
0
投票

您应该使用具有[[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} /> ); };