React 之 Hook
什么是 Hook?
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
(如 函数式组件)。
Hook 是一些可以让你在 函数组件 里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。
Hook 使用规则
Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
- 只能
在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。 - 只能
在 React 的函数组件中调用 Hook,不要在其他 JavaScript 函数中调用。(还能在自定义的 Hook 中调用 Hook)。
State Hook
useState 会返回一对值:当前状态 和一个让你 更新它的函数
import React, { useState } from 'react';
function Example() {
// 声明一个新的叫做 “count” 的 state 变量
const [count, setCount] = useState(0);
const [todo, setTodo] = useState({dosomething: "aaa"});
return (
<div>
<p>You clicked {count} times</p>
<p>You clicked {todo.dosomething} times</p>
<button onClick={() => {
setCount(count + 1);
setTodo({dosomething: "bbb"})
}}>
Click me
</button>
</div>
);
}
Effect Hook
useEffect 就是一个 Effect Hook,,给函数组件增加了操作副作用的能力 (副作用函数) 。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。
例如,下面这个组件在 React 更新 DOM 后会设置一个页面标题:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 相当于 componentDidMount 和 componentDidUpdate:
// 组件初始渲染及数据更新导致的渲染都会调用 useEffect 内部事件
useEffect(() => {
// 使用浏览器的 API 更新页面标题
document.title = `You clicked ${count} times`;
alert("update"); // 每次更新count都会执行
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
副作用函数还可以通过返回一个函数,来指定如何“清除”副作用(防止引起内存泄露):
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}