Reputation: 260
I have this parent component that has this state which is an object, one of the properties is a function called onScrollbarSelection, that makes an axios post. All of this is going to be passed to the child component.
The child component uses an API from Highcharts, one of the properties ( afterSetExtremes ) of the API uses the onScrollbarSelection function from the parent (props). The problem is that afterSetExtremes can trigger a lot of consecutive times which is making the onScrollbarSelection function execute a lot of consecutive times as well and making a lot of axios posts, crashing the browser.
I've tried putting a timeout on the post call, but didn't work, it still calls makes the axios post a lot of times. How can I prevent from onScrollbarSelection (or the afterSetExtremes event) from executing a lot of consecutive times?
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>
);
}
Upvotes: 2
Views: 438
Reputation: 11633
You can also try to implement setTimeout and clearInterval into your onScrollbarSelection functionality. Like in the demo below, where wanted functions is triggered only once:
Demo: https://jsfiddle.net/BlackLabel/c0e9L6nf/
xAxis: {
events: {
afterSetExtremes() {
myStopFunction()
myFunction()
}
}
}
EDIT:
Here is a demo with reproduction of the above proposal using React: https://stackblitz.com/edit/react-adeke4?file=index.js
Upvotes: 0
Reputation: 1575
You should use the function with debounce effect.
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}
/>
);
};
Upvotes: 2