官网说的,即使Hook出来,也不会替代Class,但是作为一名合格的程序媛,是需要不断学习的,这篇博客主要写给自己,按照自己理解的思路来的,当于做了个笔记。
一提到Hook,第一反应就是useState和useEffect,但是在记录这两个关键词之前,得先说说整体的变化。
整体由Class的写法变成了函数的写法
import React from 'react';
function Home() {
...
}
export default Home
当然,也可以
import React from 'react';
export default function Home() {
...
}
如果父组件传来值,同样在函数那里接受props
import React from 'react';
function Home(props) {
...
}
这里和Class写法有点区别,Class写法中props存在在当前组件的作用域中,如果不对props有过多的操作,可以省略constructor和super,或者写他们的时候不带props,完整继承父类的信息。函数写法如果不在那里写props就无法接收到父类的传值,且函数内部使用props的时候不需要使用this引用,state同(后文会提及)。
useState
首先讨论useState,在Class写法中,state定义在constructor中,this.state里面放着初始化的值,this.setState()重定义state里面的值,在Hook里面,用useState定义,定义的规范是
import React, { useState } from 'react';
...
const [count, setCount] = useState(0);
其中:
- count是state里面的字段名字
- setCount可以理解为setState的名字
- useState(0)则是初始化给它的值,不仅仅是数字,可以是’{}’、’[]'等等
上文代码转译为Class写法为:
constructor(){
super()
this.state={
count:0
}
}
setCount的使用方式,可以参考下文:
<Input onPressEnter={(e) => { setCount(e.target.value) }} />
就像this.state里面的字段不止一个一样,useState也可以不止定义一个。
引用state的时候,不需要像class写法一样用this.state,直接引用该定义的字段就行。
...
<input value = {count} />
...
useEffect
在Class写法中,组件的初始化、渲染、销毁离不开生命周期,而useEffect将Class中的componentDidMount,componentDidUpdate 和 componentWillUnmount这三个生命周期做了个组合。降低了维护成本(Class写法中经常会遇到渲染完后prop或者state发生变化无法实时更新,找半天bug后才知道用componentDidUpdate解决,然而那个生命周期解决不好就是死循环)
在Hook中定义和引用:
import React, { useState, useEffect } from 'react';
...
useEffect(() => {
...
return () => {
cleanup
}
}, [input])
其中:
- 前文提到,props的接受由最外层的函数接受,在useEffect内可直接引用props,不用this.props
- useEffect一般情况下不用销毁,如果有需要销毁的情况可返回清理函数,即return那里的函数。
- 最后一个数组是定义可跳过的字段,因为useEffect从组件第一次渲染的时候就会执行,可能为了节约性能,可能不需要每一次都加载。官网说之后的更新会考虑默认最后一个数组包含全部字段,现在默认的是空数组,且该字段可选
- 和useState一样,一个组件中useEffect可以有多个,但是需要注意一点,后一个useEffect加载的时候,前一个useEffect自动销毁。
基本的学习到此为止。官网针对Hook提供了context、reducer、ref等Hook
需要的时候再做笔记。
如果文章有错也欢迎指正。