什么时候需要用到hook?
编写函数组件并意识到需要向其添加一些 state,以前的做法是必须将其它转化为 class,现在可以在现有的函数组件中使用 Hook,同时它也简化来一些原先需要生命周期等操作
useState:返回一个两个参数的数组,第一个参数是变量,第二个是函数
function Test() {
const [count, setCount] = useState(0) // 括号内的是初始化的值
}
// 相当于
class Test extends Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
function setCount(value) {
this.setState({count:value})
}
}
列表的话,可以这样处理
const [list, setList] = useState([{text: 1}, {text: 2}, {text: 3}])
<button onClick={() => setList([...list, {text: 4}])}></button>
由此可见,代码的阅读性和简洁性都大大提高了,使用也可以直接使用声明的变量
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Click me +1</button>
// 相当于
function setCount(value) {
this.setState({count:value})
}
const count = this.state
<p>{this.state.count}</p>
<button onClick={() => setCount(count + 1)}>Click me +1</button>
useEffect:相当于componentDidMount
,componentDidUpdate
和 componentWillUnmount三个生命周期
为什么在组件内部调用 useEffect
?
将 useEffect
放在组件内部让我们可以在 effect 中直接访问 count
state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存函数作用域中。Hook 使用了 JavaScript 的闭包机制。
// return前的代码相当于componentDidMount,componentDidUpdate
// componentWillUnmount的操作由return出的函数执行
useEffect(() => {
fetch("/list").then()
console.log("组件加载或更新")
return () => {
console.log("清除操作")
}
})
性能优化点:原先componentDidUpdate可以通过prevProps
或 prevState比较来减少性能消耗
useEffect同样也可以利用一个变量的变化来做这种操作
useEffect(() => {
console.log("组件加载或更新")
},[count]) // 当count变化的时候才会更新,如果useEffect只想执行一次,之后都不执行,可以传入空数组[]
使用ESLint来规范HOOK书写
npm install eslint-plugin-react-hooks --save-dev
{
"plugins": [
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks": "error", // 检查 Hook 的规则
"react-hooks/exhaustive-deps": "warn" // 检查 effect 的依赖
}
}
Hook 要在组件的最顶层调用,即不能被函数或者逻辑语句包裹
自定义Hook可以将不同组件内的相同部分的Hook进行封装