React Hooks模拟组件生命周期

Hooks模拟constructor

Hooks模拟constructor

constructor(){
  super()
  this.state={count:0}
}

const [count setCount]=useState(0)

Hooks模拟componentDidMount

useEffect拥有两个参数,第一个参数作为回调函数会在浏览器布局和绘制完成后调用,因此它不会阻碍浏览器的渲染进程,第二个参数是一个数组,也是依赖项
1、当依赖列表存在并有值,如果列表中的任何值发生更改,则每次渲染后都会触发回调
2、当它不存在时,每次渲染后都会触发回调
3、当它是一个空列表时,回调只会被触发一次,类似于componentDidMount

componentDidMount(){
 console.log('I am mounted')
}
useEffect(()=>console.log('mounted'),[])

模拟shouldComponentUpdate

React.memo包裹一个组件来对它的props进行浅比较,但这不是一个hooks,因为它的写法和hooks不同,其实React.memo等效于PureComponent,但它只比较props

shouldComponentUpdate(nextProps,nextState){
   console.log('shouldComponentUpdate')
   return true //更新组件 反之不更新
}


// 模拟shouldComponentUpdate
const MyComponent=React.memo(
  _MyComponent,
  (prevProps,nextProps)=>nextProps.count!==preProps.count
)

Hooks模拟componentDidUpdate

这里的回调函数会在每次渲染后调用,因此不仅可以访问componentDidUpdate,还可以访问componentDidMount,如果只想模拟componentDidUpdate,我们可以这样来实现

useRef在组件中创建“实例变量”,它作为一个标志来指示组件是否处于挂载或更新阶段。当组件更新完成后在会执行else里面的内容,以此来单独模拟componentDidUpdate

componentDidMount() {console.log('mounted or updated');}
componentDidUpate(){console.log('mounted or updated')}
//Hooks模拟componentDidUpdate
useEffect(()=>console.log('mounted or updated'))

const mounted=useRef()
useEffect(()=>{
 if(!mounted.current){mounted.current=true}else{console.log('I am didUpdate')}
})

Hooks模拟componentWillUnmount

此处并不同于willUnMount porps发生变化即更新,也会执行结束监听
准确的说:返回的函数会在下一次effect执行之前,被执行
当在useEffect的回调函数中返回一个函数时,这个函数会在组件卸载前被调用。我们可以在这里清除定时器或事件监听器。

componentWillUnmount(){
  console.log('will unmount')
}
//hooks
useEffect(()=>{

 return ()=>{console.log('will unmount')}
},[])

模拟的生命周期和class中的生命周期有什么区别吗? useEffect中return执行时机

代码测试地址:https://codesandbox.io/s/useeffect-clean-forked-xq56bg

1、默认的useEffect(不带[]或者监听的[count有变化])中return的清理函数,它和componentWillUnmount有本质区别的,默认情况下return,在每次useEffect执行前都会执行,并不是只有组件卸载的时候执行。每次执行前会拿到上次的值,如果是空数组则在组件销毁时执行

2、useEffect在副作用结束之后,会延迟一段时间执行,并非同步执行,和compontDidMount有本质区别。遇到dom操作,最好使用useLayoutEffect。

hooks 模拟的生命周期与class中的生命周期不尽相同,我们在使用时,还是需要思考业务场景下那种方式最适合。

posted @ 2023-02-20 09:26  Leise  阅读(260)  评论(0编辑  收藏  举报