Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 自定义 hook 实现验证码倒计时 #2

Open
heycn opened this issue Dec 28, 2022 · 1 comment
Open

React 自定义 hook 实现验证码倒计时 #2

heycn opened this issue Dec 28, 2022 · 1 comment

Comments

@heycn
Copy link
Owner

heycn commented Dec 28, 2022

避免陷入闭包陷阱

import React, {useEffect, useState} from 'react'

const useCountDown = second => {
  const [seconds, setSeconds] = useState(second)
  useEffect(() => {
    setTimeout(() => {
      if (seconds > 0) {
        setSeconds(seconds - 1)
      }
    }, 1000)
  }, [seconds])

  return [seconds, setSeconds]
}

const App = () => {
  const [seconds, setSeconds] = useCountDown(0)
  return (
    <button disabled={seconds !== 0} onClick={() => setSeconds(60)}>
      {seconds > 0 ? `${seconds}s后可点击` : '点击开始倒计时'}
    </button>
  )
}
@heycn
Copy link
Owner Author

heycn commented Apr 27, 2023

如果你想严格地控制 Timer 的执行次数,请使用使用 useRef + clearInterval,并且在 useEffect 中的 return => {} 里调用

import { useEffect, useRef, useState } from 'react'

type CountDown = (second: number) => [number, (seconds: number) => void]
export const useCountDown: CountDown = second => {
  const [seconds, setSeconds] = useState(second)
  const timer = useRef<number>()

  useEffect(() => {
    if (seconds > 0) {
      timer.current = window.setTimeout(() => {
        console.log('update')
        setSeconds(seconds - 1)
      }, 1000)
    }
    return () => window.clearInterval(timer.current)
  }, [seconds])

  return [seconds, setSeconds]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant