How to read and modify a state in useEffect IAW 'exhaustive-deps' lint rule

后端 未结 4 997
轮回少年
轮回少年 2021-01-25 19:05

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.

Of note, I\'m using \"

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-25 19:37

    I think the issue here is that your approach to accommodating this linter rule is too passive. You are running all the code in the useEffect callback any time it runs, but you really only want to execute that stuff when the data changes.

    So you can reflect that in your code:

    const [shouldUpdateOverlay, setShouldUpdateOverlay] = useState(false);
    
    useEffect(() => {
        if (shouldUpdateOverlay) {
            // 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);
    
            // Show the new overlay on my map
            map.addOverlays(newOverlay);
    
            // 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);
            setShouldUpdateOverlay(false);
        }
    }, [map, overlay, shouldUpdateOverlay data, generateNewOverlay]);
    
    // use from event handlers, etc.
    const updateData = (newData) => {
        setData(newData);
        setShouldUpdateOverlay(true);
    };
    

    Realistically, this is an overwrought approach to accomplishing the same thing you could achieve by having [data] as the only dependency in useEffect, since that's really the only dependency that matters there. However, I believe the above should allow you to achieve what you are trying to do without violating the linter rule.

提交回复
热议问题