一个计时器,直接看代码
import * as React from 'react'
const {useEffect, useState } = React
const Counter:React.FC<{}> = () => {
const [count, setCount] = useState(0)
const step = 1
useEffect(() => {
const timer = setInterval(() => {
setCount(count + step)//所以count只会改变一次,由0=>1
},1000)
return () => {
clearInterval(timer)
};
}, [])//因为useEffect(callback,[])只在dom渲染完成之后会执行一次callback
return (
<>
<div>{count}</div>
</>
)
}
export default Counter
useEffect(callback,[]),因为callback仅会在dom渲染完成之后执行一次,后续任何state发生变化,callback都不会执行,所以setCount(count + step) //count 由 0=>1后不会发生变化。
为了达到count每秒都递增step的需求,可以调整为setCount(curCount => curCount+step)。
而若step也是动态的呢?则可以用useReducer实现:
import * as React from 'react'
import { Button } from 'antd';
const {useEffect,useReducer } = React
export interface IState {
count:number,
step:number
}
export interface IAction {
type:string
payload?:any
}
export interface IState {
count:number
step:number
}
const reducer = <T extends IState>(state:T, action:IAction):T => {
const {count,step} = state
switch (action.type){
case 'TICK':
return {...state,count:count+step}
case 'INCREASESTEP':
return {...state,step:step+1}
case 'DECREASESTEP':
return {...state,step:step-1}
default:
return state
}
}
const UseEffect:React.FC<{}> = () => {
const initState:IState = {
count:0,
step:1
}
const [state,dispatch] = useReducer(reducer, initState)
useEffect(() => {
const timer = setInterval(() => {
dispatch({type:'TICK'})
},1000)
return () => {clearInterval(timer)}
},[])
const {increaseStep,decreaseStep} = React.useMemo(() => {
return (
{
increaseStep:() => {
dispatch({type:'INCREASESTEP'})
},
decreaseStep:() => {
dispatch({type:'DECREASESTEP'})
}
}
)
},[])
return (
<div>
<div>Step:{state.step}</div>
<div>Count:{state.count}</div>
<Button onClick={increaseStep}>Change Step +</Button>
<Button onClick={decreaseStep}>Change Step -</Button>
</div>
)
}
export default UseEffect