Hooks 是一项新功能提案,可让您在不编写类的情况下使用 React 功能
为什么引入Hook(借鉴一下React官网)
- 在组件之间重用有状态逻辑很困难
React并没有为组件提供一种可重复使用行为的方法,使用 Hook ,您可以从组件中提取有状态逻辑,以便可以独立测试并重用。Hooks 允许您在不更改组件层次结构的情况下重用有状态逻辑。 这样可以轻松地在许多组件个之间或与社区共享 Hooks 。
- 复杂的组件变得难以理解
我们常常不得不维护一些组件,这些组件一开始很简单,但后来却变成了一堆难以管理的有状态逻辑和副作用。每个生命周期方法通常包含一组不相关的逻辑。例如,组件可能在componentDidMount 和 componentDidUpdate中执行一些数据获取。然而,相同的 componentDidMount 方法可能还包含一些不相关的逻辑,它们设置事件监听器,并在 componentWillUnmount 中执行清理。一起更改的相互关联的代码会被分离,但是完全不相关的代码最终会组合在一个方法中。这很容易引入错误和不一致。
- 人和机器都容易混淆的 类(class)
类(class) 可能是学习 React 的一大障碍。您必须了解 this 在 JavaScript 中是如何工作的, this 与多数语言中的工作方式有很大不同。您必须记住绑定事件处理程序。
useState
useState用于为函数组件引入状态(state);useState的唯一参数是初始状态(state);useState返回一对:current state(状态)值和一个允许你更新它的函数;
import React, { useState } from 'react';
const Index = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default Index;
特别说明:
useState 修改引用类型的state的时候,需要改变指针地址,才会触发渲染
useEffect
-
可以将
useEffectHook 视为componentDidMount,componentDidUpdate和componentWillUnmount的组合 -
每次渲染后
useEffect都会运行 -
useEffect 具有副作用,像 addEventListener、setTimeout 等需要进行清理
-
使用多个 Effects 来分离关注点
function FriendStatusWithCounter(props) {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
// ...
}
useContext
-
接受一个 context(上下文)对象(从
React.createContext返回的值)并返回当前 context 值 -
跨祖孙组件传递数据
const UserContext = createContext({
name: 'zhangsan',
age: 12,
sex: 0,
});
const Child = () => {
const userInfo = useContext(UserContext);
return (
<div>
我是{userInfo.name},今年{userInfo.age},性别{userInfo.sex}
</div>
)
}
const Parent = () => {
const [userInfo, setUserInfo] = useState({
name: 'zhangsan',
age: 12,
sex: 0,
});
const changeName = () => {
setUserInfo({
...userInfo,
name: userInfo.name === 'lisi' ? 'zhangsan' : 'lisi',
});
}
return (
<div>
<UserContext.Provider value={userInfo}>
<Child />
</UserContext.Provider>
<button onClick={changeName}>修改name</button>
</div>
)
}
Hooks 使用规则
Hooks 是 JavaScript 函数,但在使用它们时需要遵循两个规则。
-
只在顶层调用Hook,不要在循环,条件或嵌套函数中调用 Hook
-
只在 React Functions 中调用 Hooks