Skip to content
This repository has been archived by the owner on Jun 2, 2023. It is now read-only.

How do you make decisions when there are so many options? e.g.: useEffect vs Callback #801

Open
hoop71 opened this issue Mar 29, 2020 · 0 comments

Comments

@hoop71
Copy link

hoop71 commented Mar 29, 2020

Hi Kent!

I came across a situation where I need to have an event listener on the window and also need access to a piece of state in a component when that event is handled.

I was hoping to get your feedback on how you might approach this problem? How would go going about deciding which of these, or another option, to implement. Is there a way you think about such problems that inform your decisions?

Thanks!

Codesandbox Demo:

The problem: When the event listener is attached to the window the state becomes stale, and we need a way to access it.

I came up with two solutions and could also make a case for a third using useRef():

  1. useEffect where I remove then add back the event listener when that piece of state changes.
  const [activeColor, setActiveColor] = useState('')

  const handleKeyDown = useCallback(
    ({ key }) => {
      if (Object.keys(keyColorDictionary).includes(key)) {
        // Color that matched the key press
        const selectedColor = keyColorDictionary[key];
        // if the key is same as activeColor, turn it off
        // otherwise set it to selectedColor
        setActiveColor(selectedColor === activeColor ? "" : selectedColor);
      }
    },
    [activeColor]
  );

  useEffect(() => {
    // setup event listener
    window.addEventListener("keydown", handleKeyDown);
    return () => {
    // teardown event listener
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [handleKeyDown]);
  1. Pass a callback to the event listener that accesses the state needed.
  const [activeColor, setActiveColor] = useState('')

  const handleKeyDown = ({ key }, setActiveColor) => {
    if (Object.keys(keyColorDictionary).includes(key)) {
        // Color that matched the key press
        const selectedColor = keyColorDictionary[key];
        // if the key is same as activeColor, turn it off
        // otherwise set it to selectedColor
      setActiveColor(selectedColor === activeColor ? "" : selectedColor);
    }
  };

  useEffect(() => {
    // pass setActiveColor to keyDown handler to give access to current state
    const handleKeyDownAndSetActiveColor = e => handleKeyDown(e, setActiveColor);
    // setup event listener
    window.addEventListener("keydown", handleKeyDownAndSetActiveColor);
    // teardown event listener
    return () => {
      window.removeEventListener("keydown", handleKeyDownAndSetActiveColor);
    };
  }, []);
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant