Skip to content

Hooks

Hooks#

本章主要包含以下内容:

Hooks 基本介绍#

HookReact 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

Hooks 的出现,首先能解决如下的一些问题:

import React from 'react'
// 类组件
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0,
}
}
componentDidMount() {
document.title = `你点击了${this.state.count}`
}
componentDidUpdate() {
document.title = `你点击了${this.state.count}`
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
)
}
}
export default App

另外,Hooks 的出现,还有更加重要的一个信号,那就是整个 React 思想上面的转变,从“面向对象”的思想开始转为“函数式编程”的思想。这是编程范式上面的转变。

编程范式:

声明式编程并不是新的产物,它是和命令式编程同期出现的。但是,早期更加流行命令式编程。不过随着近几年整个项目工程越来越复杂,以前的命令式编程就有点力不从心,所以现在慢慢开始流行声明式编程。

因此当你学习 Hooks 的时候,会发现突然多了一些以前不熟悉的概念,例如:纯函数、副作用、柯里化、高阶函数等概念。

当然,你可能好奇“面向对象”和“函数式编程”有什么区别,这里推荐一篇文章:

https://www.imaginarycloud.com/blog/functional-programming-vs-oop/

Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:

useStateuseEffect#

React 内置了一些实用的 Hook,并且随着 React 版本的更新,Hook 的数量还在持续增加当中。

入门阶段,我们掌握两个最常用的 Hook,一个是为函数组件添加状态的 useState,另一个是处理函数副作用的 useEffect

useState 包含以下的知识点:

import { useState } from 'react'
function App(props) {
let [count, setCount] = useState(0)
function clickhandle() {
setCount(++count)
}
return (
<div>
<div>{count}</div>
<button onClick={clickhandle}>+1</button>
</div>
)
}
export default App
import { useState } from 'react'
function App(props) {
let [age, setAge] = useState(18)
const [fruit, setFruit] = useState('banana')
const [todos, setTodos] = useState([{ text: '学习 Hook' }])
function clickhandle() {
setAge(++age)
}
return (
<div>
<div>年龄:{age}</div>
<div>水果:{fruit}</div>
<div>待办事项:{todos[0].text}</div>
<button onClick={clickhandle}>+1</button>
</div>
)
}
export default App

useEffect 包含以下知识点:

import { useState, useEffect } from 'react'
function App() {
let [count, setCount] = useState(0)
useEffect(() => {
// 书写你要执行的副作用,会在组件渲染完成后执行
document.title = `你点击了${count}`
})
function clickhandle() {
setCount(++count)
}
return (
<div>
<div>你点击了{count}</div>
<button onClick={clickhandle}>+1</button>
</div>
)
}
export default App
import { useState, useEffect } from 'react'
function App() {
let [count, setCount] = useState(0)
useEffect(() => {
// 书写你要执行的副作用,会在组件渲染完成后执行
const stopTimer = setInterval(() => {
console.log('Hello')
}, 1000)
// console.log("副作用函数执行了");
// 在 useEffect 中,可以返回一个函数,该函数我们称之为清理函数(一般就是做一些清理操作)
// 该函数会在下一次渲染之后,但是在执行副作用操作之前执行
return () => {
// console.log("清理函数执行了");
clearInterval(stopTimer)
}
})
function clickhandle() {
setCount(++count)
}
return (
<div>
<div>你点击了{count}</div>
<button onClick={clickhandle}>+1</button>
</div>
)
}
export default App

自定义 Hook#

除了使用官方内置的 Hook,我们还可以自定义 Hook,自定义 Hook 的本质其实就是函数,但是和普通函数还是有一些区别,主要体现在以下两个点:

App.jsx

import { useState } from 'react'
import useMyBook from './useMyBook'
function App() {
const { bookName, setBookName } = useMyBook()
const [value, setValue] = useState('')
function changeHandle(e) {
setValue(e.target.value)
}
function clickHandle() {
setBookName(value)
}
return (
<div>
<div>{bookName}</div>
<input type="text" value={value} onChange={changeHandle} />
<button onClick={clickHandle}>确定</button>
</div>
)
}
export default App

useMyBook

import { useState } from 'react'
function useMyBook() {
const [bookName, setBookName] = useState('React 学习')
return {
bookName,
setBookName,
}
}
export default useMyBook