为什么函数在react and Chart.js中不使用`usecallback'更新

发布于 2025-02-09 20:58:30 字数 2585 浏览 2 评论 0原文

背景:我正在使用React和Chart.js显示条形图。我还使用Chartjs-Plugin-DragdataChartjs-Plugin-Zoom在某些限制内拖动和缩放我的图表。

我正在尝试做的事情:在DragData插件中,可以选择使用自定义的 ondragstart 和ondragend andragend 函数(doc:doc:doc: https://github.com/chrispahm/chrispahm/chartjs-plugin-plugin-dragdata )选项对象。每当更新某个状态时,我都想更改此功能。该状态已在另一个组件中更新,我可以通过usefect挂钩收听其更改。

// 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值值,从不修改或更新它。

我尝试的:从我的理解中,它与函数值围绕值关闭的方式有关,因此,我也尝试使用usecallback hook在<<<<<<<<<代码> ActiveState 更改,无成功。

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为选项对象本身和更多组合尝试,但是您可能认为我还不习惯钩子的工作方式。如有必要,我还可以提供更多信息

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尸血腥色 2025-02-16 20:58:30

它看起来像Chardjs-Plugin-Dragdata登录事件有关inialization的事件,并且以后不会更新它们。您需要使用useref获得当前值。

const { activeState } = useContext(CertainContext);

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

...

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

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);
          },
      }
  }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文