Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
Hook的含义:
Hook 这个单词的意思是"钩子"。
React Hooks 的意思是,组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来。 React Hooks 就是那些钩子。
你需要什么功能,就使用什么钩子。React 默认提供了一些常用钩子,你也可以封装自己的钩子。
所有的钩子都是为函数引入外部功能,所以 React 约定,钩子一律使用use前缀命名,便于识别。你要使用 xxx 功能,钩子就命名为 usexxx。
Hook的优点
Hook规则
State Hook
useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。
import React, { useState } from 'react';
function Count() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
上面代码中,Count组件是一个函数,内部使用useState()钩子引入状态。
useState()这个函数接受状态的初始值,作为参数,上例的初始值为0。该函数返回一个数组,数组的第一个成员是一个变量(示例代码中是count),指向状态的当前值。第二个成员是一个函数,用来更新状态,约定是set前缀加上状态的变量名(示例代码中是setCount)。
Effect Hook
useEffect()用来引入具有副作用的操作,最常见的就是向服务器请求数据。以前,放在componentDidMount里面的代码,现在可以放在useEffect()。
useEffect()的用法如下。
useEffect(()=>{
//一些操作
},[dependencies])
useEffect()接受两个参数。第一个参数是一个函数,异步操作的代码放在里面。第二个参数是一个数组,用于给出 Effect 的依赖项,只要这个数组发生变化,useEffect()就会执行。第二个参数可以省略,这时每次组件渲染时,就会执行useEffect()。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Context Hook
如果需要在组件之间共享状态,可以使用useContext()。
现在有两个组件 One和 Two,我们希望它们之间共享状态。首先使用 React Context API,在组件外部建立一个 Context。
const AppContext = React.createContext({});
<div className="Root">
<One/>
<Two/>
<div>
上面代码中,AppContext.Provider提供了一个 Context 对象,这个对象可以被子组件共享。
One 组件的代码如下:
const One =()=>{
const { username }=useContext(AppContext);
return(
<div>
<p>我是第一个页面</p>
<p>{username}</p>
</div>
);
}
上面代码中,useContext()钩子函数用来引入 Context 对象,从中获取username属性。
Two 组件的代码也类似:
const Two=()=>{
const { username }=useContext(AppContext)
return(
<div>
<h1>Two</h1>
<p>我是第二个页面</p>
<p>{username}</p>
</div>
);
}
自定义Hook
通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。
示例:
import { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
useFriendStatus 的 Hook 目的是订阅某个好友的在线状态。这就是我们需要将 friendID 作为参数,并返回这位好友的在线状态的原因。