我有一个具有此状态的父组件,它是一个对象,属性之一是一个称为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>
);
}
您应该使用具有[[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}
/>
);
};