本文介绍了如何读取和修改 useEffect IAW 'exhaustive-deps' lint 规则中的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张带有叠加层的地图.我有一个效果,当基础数据发生变化时,删除旧的叠加层并重新绘制一个新的叠加层.

I have a map which has an overlay. I have an effect which, when the underlying data changes, deletes the old overlay and re-draws a new one.

值得注意的是,我正在使用 "react-hooks/exhaustive-deps" 并且它似乎来自 我读到的所有内容 只是删除依赖overlay 不是正确的答案(但它确实有效).

Of note, I'm using "react-hooks/exhaustive-deps" and it seems from everything I read that just removing the dependency overlay is not the right answer (but it does work).

注意,data 是传入的 prop.

Of note, data is a prop passed in.

useEffect(() => {
    // remove the overlay if it is there,
    // I should have overlay as a dependency per exhaustive-reps react eslint rule
    if (overlay) map.removeOverlays(overlay);

    // Generate the new overlay based on the new data (useCallback function)
    const newOverlay = generateNewOverlay(data)

    // Store the new overlay so I can remove it later if the data changes
    // Doesn't need to be done right away though, just before next render
    setOverlay(newOverlay);

    // Show the new overlay on my map
    map.addOverlays(newOverlay);
  }, [map, overlay, data, generateNewOverlay]);

这当然会是一个无限循环,因为我正在设置叠加层并使其成为依赖项.我也不喜欢在效果中立即使用 setState ,因为它会导致另一个渲染.我错过了什么?我如何实现这个逻辑?

This of course will be an infinite loop because I'm setting overlay and making it a dependency. I also don't like using setState immediately in an effect as it causes another render. What am I missing? How do I achieve this logic?

我确实阅读了大约 5 个类似标题的问题,但他们没有回答我的问题.

I did read about 5 similarly titled questions, but they did not answer my question.

类似的问题,但不问而保持详尽的-reps deps lint 规则,这不是'这对他们来说不是一个因素,因为他们在更改状态之前没有读取状态.

Similar question, but not asking while keep exhaustive-reps deps lint rule which isn't a factor for them because they aren't reading the state before changing it.

我仍然遇到 useState 和 reducer 应该是纯的问题.我遇到问题的依赖项 (overlay) 的目的是我必须检查覆盖是否存在.如果是这样,我需要做一个非纯的事情,即在设置我的新叠加层之前从地图中删除该叠加层.这行代码使它变得不纯:

I still have the problem where useState and a reducer should be pure. The purpose of the dependency I'm having an issue with (overlay) is that I have to check if overlay exists. If it does, I need to do a non-pure thing which is remove that overlay from the map before setting my new overlay. This line of code is what makes it not pure:

if (overlay) map.removeOverlays(overlay);

如果没有那条线,我的依赖项列表中永远不需要 overlay 并且这整个事情都不会成为一个因素.正如您所看到的,由于该行,接受的答案并不纯粹.

Without that line, I'd never need overlay in my dependency list and this entire thing wouldn't be a factor. As you can see the accepted answer is not pure because of that line.

useReducer 答案在减速器之外有这一行,所以 overlay 应该是一个依赖项,或者它需要进入减速器.第一个选项是我试图通过 "react-hooks/exhaustive-deps" 避免的,而第二个答案并不纯粹.

The useReducer answer has this line outside the reducer so overlay should be a dependency or it needs to go in the reducer. The first option is what I'm trying to avoid by the "react-hooks/exhaustive-deps" and the second answer is not pure.

感谢任何帮助.

最终

我发现解决这个问题的最好方法是正确使用 useEffect 中的清理.我需要状态,以便以后可以从地图中删除内容.

I found the best way to approach this was to use the cleanup in useEffect properly. I was requiring state so that I could remove things from a map later.

useEffect(() => {
    // remove the overlay if it is there,
    // I originally needed this to store the overlay so I could remove it later, but if I use cleanup properly this isn't needed
    // if (overlay) map.removeOverlays(overlay);

    // Generate the new overlay based on the new data (useCallback function)
    const newOverlay = generateNewOverlay(data)

    // Store the new overlay so I can remove it later if the data changes
    // Doesn't need to be done right away though, just before next render (This is what a cleanup is!)
    // setOverlay(newOverlay);

    // Show the new overlay on my map
    map.addOverlays(newOverlay);

    // New code below
    return () => {map.removeOverlays(newOverlay)};
  }, [map, data, generateNewOverlay]);

推荐答案

你可以在setOverlay中使用一个函数:

You can use a function inside of setOverlay:

useEffect(() => {
  setOverlay(prev => {
    // remove the overlay if it is there,
    // I should have overlay as a dependency per exhaustive-reps react eslint rule
    if (prev) map.removeOverlays(prev);

    // Generate the new overlay based on the new data (useCallback function)
    const newOverlay = generateNewOverlay(data)

    // Show the new overlay on my map
    map.addOverlays(newOverlay);
    return newOverlay;
  });

}, [map, data, generateNewOverlay]);

prev 参数中,您可以获得overlay 的当前状态.这样您就不必将 overlay 状态变量添加到依赖数组中.因此,当 overlay 更新时,效果不会触发.

In the prev parameter you get the current state of overlay. This way you don't have to add the overlay state variable to the dependency array. Hence, the effect won't trigger when overlay updates.

这篇关于如何读取和修改 useEffect IAW 'exhaustive-deps' lint 规则中的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 15:17