0

I am building a todo app where in each todo the user submits, the user is allowed to edit that todo later if he/she wants. I want the todo to be editable only when the todo is tapped twice under 600ms. Failing to find any other solutions to this problem, I stumbled upon the below given solution.

    const [tappedOnce, setTappedOnce] = React.useState(false)

    const onTap = () => {
        if (tappedOnce) {
            setEditable(true)
            setTimeout(() => todoRef.current.focus())
            setTappedOnce(false)

        } else setTappedOnce(true)
    }

    React.useEffect(() => {
        const intId = setInterval(() => {
            setTappedOnce(false)
        }, 600)

        return () => clearInterval(intId)
    }, [])

In the solution, I am resetting the tappedOnce state value to false every 600ms. But as you can probably guess, if the user has 50 todos, then I will have 50 concurrent setInterval processes running at the same time. Is this going to affect the performance of the app by any significant margin? Are there any better solution to this problem?

KMA Badshah
  • 895
  • 8
  • 16

2 Answers2

1

here an alternative approach, using just a ref to store the moment of the last click/tap/whatever

const lastClick = useRef(NaN);

const onTap = event => {
  const timeStamp = event.timeStamp; // or Date.now()
  if (timeStamp - lastClick.current < 600) {
    lastClick.current = NaN;
    setTimeout(() => todoRef.current.focus());
  } else {
    lastClick.current = timeStamp;
  }
}
Thomas
  • 11,958
  • 1
  • 14
  • 23
  • why `useRef()` and not `useState()`? – KMA Badshah Nov 22 '20 at 11:59
  • because I don't need/want to rerender when the user clicked once. Maybe not even when he clicked twice, like in this case; we don't need to rerender to set the focus. Imo. `useRef` is the best option of a "state without rerender". I'd use a state when that state affects the view. – Thomas Nov 22 '20 at 12:04
  • And `lastClick.current` is synchronous, it will always hold the latest value. Even if I memoize `onTap`. I don't need to worry/handle that I might deal with a closure over an outdated state. – Thomas Nov 22 '20 at 12:07
  • why not just use store `lastClick` on a plain variable if state doesn't matter? – KMA Badshah Nov 22 '20 at 15:31
0

YES! Multiple concurrent setInterval() does affect performance. If they are not cleared they will just continue running, and it's a hassle keeping track of id's to clear if you have other intervals.

You could use a timeout instead. Whenever you click you set recentClick = true Then you use a setTimeout(b) to make recentClick = false after the 600ms.

agiopnl
  • 1,190
  • 9
  • 18