为什么函数在React和Chart.js中不使用'useCallback'进行更新

jhdbpxl9  于 2022-11-07  发布在  Chart.js
关注(0)|答案(1)|浏览(113)

背景:我使用React和chart.js来显示一个条形图,还使用chartjs-plugin-dragdatachartjs-plugin-zoom在一定范围内拖动和缩放图表。

"我想做的是“在dragdata插件中,有一个选项可以用自定义的函数修改onDragStartonDragEnd函数(doc:https://github.com/chrispahm/chartjs-plugin-dragdata)。我想在某个状态更新时更改此函数。该状态在另一个组件中更新,我可以通过useEffect钩子监听它的更改。

// works when setActiveState is called
useEffect(()=> {
    console.log(activeState) // changes from state_1 to state_2
}, [activeState]);

而在实际代码中:

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

问题是,无论我尝试什么,onDragStart函数似乎都在“保存”第一个activeState值,而从不修改或更新它。

我尝试的:根据我的理解,这与react如何接近函数中的值有关,因此我也尝试在activeState发生变化时使用useCallback钩子重新计算函数,但没有成功。

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

我确信组件正在重新呈现,但该函数仍然没有重新呈现。选项中的其他值正在更新。例如:

const options = {
        // other options
        plugins: {
            zoom: {
                wheel: {
                    enabled: activeState === "state_1" // This actually is being updated and works
                }
            }
        }
    }

我还尝试了useMemo作为选项对象本身,以及更多的组合,但正如您可能已经意识到的,我还不太习惯钩子的工作方式。

q9rjltbz

q9rjltbz1#

看起来chartjs-plugin-dragdata在初始化时注册了事件,但之后没有更新它们。您需要使用useRef来获取当前值。

const { activeState } = useContext(CertainContext);

const ref = useRef('');
ref.current = activeState;

...

const options = {
  // other options
  plugins: {
      dragData: {
          onDragStart: () => {
            console.log(ref.current);
          },
      }
  }
}

相关问题