Background: I'm using React and chart.js to display a bar chart. I'm using also the chartjs-plugin-dragdata
and chartjs-plugin-zoom
to drag and zoom my chart within certain limits.
What I'm trying to do: in the dragdata plugin there is the option to modify the onDragStart
and onDragEnd
functions with custom ones (doc: https://github.com/chrispahm/chartjs-plugin-dragdata) within the options object. I want to change this function whenever a certain state is updated. The state is updated in another component and I can listen to its change via the useEffect
hook.
// works when setActiveState is called
useEffect(()=> {
console.log(activeState) // changes from state_1 to state_2
}, [activeState]);
And in the actual code:
export const SomeComponent: FC = () => {
const { activeState } = useContext(CertainContext)
const data = //.. some data
const onDragStart = (event, elIndex, chartIndex)=> {
console.log(activeState) // <-- here I have the issue, always state_1
}
const options = {
// other options
plugins: {
dragData: {
onDragStart: onDragStart
}
}
}
return (
<Chart
type="bar"
options={options}
data={data}
/>
)
}
The issue is that no matter what I try, the onDragStart
function seems to "save" the first activeState
value and never modifies or updates it.
What I tried: From my understanding it has to do with how react closes around values in functions, therefore I tried also to use the useCallback
hook to recompute the function whenever the activeState
changes, without success.
export const SomeComponent: FC = () => {
const { activeState } = useContext(CertainContext)
const data = //.. some data
const onDragStart = useCallback((event, elIndex, chartIndex)=> {
console.log(activeState) // <-- here I have the issue, always state_1
}, [activeState])
const options = {
// other options
plugins: {
dragData: {
onDragStart: onDragStart
}
}
}
return (
<Chart
type="bar"
options={options}
data={data}
/>
)
}
I'm sure the component is re-rendering, but still that function in particular is not. Other values in the options are being updated. For example:
const options = {
// other options
plugins: {
zoom: {
wheel: {
enabled: activeState === "state_1" // This actually is being updated and works
}
}
}
}
I also tried with useMemo
for the options object itself and more combinations as well, but as you may have figured I'm not yet very used to how hooks are working. If necessary I can also provide more information
It looks like chartjs-plugin-dragdata
registers events on inialization and doesn't update them later. You'd need to use useRef
to get the current value.
const { activeState } = useContext(CertainContext);
const ref = useRef('');
ref.current = activeState;
...
const options = {
// other options
plugins: {
dragData: {
onDragStart: () => {
console.log(ref.current);
},
}
}
}