V16.8版本出现的HOOK的出现是为了使代码更加容易理解,而且并不打算废弃class的写法,且class会一直向后兼容。
定义react组件有两种方式:
- 函数式(无状态组件)
- es6形式的
extends React.Component
定义的组件(有状态)
HOOK的出现使得在函数内也可以操作状态state以及拥有生命周期函数。HOOK不能在class组件中使用。
1. react内置HOOK
- useState
一个函数组件中可以多次调用该函数。
返回值:返回一对值:当前状态和一个让你更新它的函数。下面是一个简单的示例。
import React, { useState } from 'react';
function Example() {
// 声明一个叫 “count” 的 state 变量,0是初始值。
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useEffect:主要用来执行一些“副作用”,比如操作DOM或者是发送请求获取数据
- 它在第一次渲染之后和每次更新之后都会执行。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 与componentDidMount 和 componentDidUpdate相似
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- 需要清除的事件则返回一个函数
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
2. 自定义HOOK
类似函数,以use开头是为了更好地区分HOOK和普通函数
import React, { 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;
}
//使用自定义的HOOK
const isOnline = useFriendStatus(props.friend.id);