1.只能在函数最外层调用HOOK.(在 React 函数中调用 Hook,)
2.只能在 React 的函数组件中调用 Hook。(自定义的 Hook 中也可以调用)
useState()
//Hook在函数组件里“钩入” React state 及生命周期等特性的函数。
// 1.useState
// useState 就是一个 Hook ,通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 state。
// 它会返回一对值:当前状态和一个让你更新它的函数,
// 类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并
import React, { useState } from 'react';
function Example() {
// 声明一个叫 “count” 的 state 变量。 可以在一个组件中多次使用 State Hook:
//useState() 方法里面唯一的参数就是初始 state
//const [count, setCount] = useState()。这与 class 里面 this.state.count 和 this.setState 类似
const [count, setCount] = useState(0);
//等号左边名字并不是 React API 的部分,你可以自己取名字 const [fruit, setFruit] = useState('banana');
// [] 数组解构。它意味着我们同时创建了 fruit 和 setFruit 两个变量,
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
// useState唯一的参数就是初始 state。在上面的例子中,我们的计数器是从零开始的,所以初始 state 就是 0。
// 值得注意的是,不同于 this.state,这里的 state 不一定要是一个对象
// 这个初始 state 参数只有在第一次渲染时会被用到。
useEffect()
//2.Effect Hook
// 相当于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
// 使用浏览器的 API 更新页面标题
document.title = `You clicked ${count} times`;
});
// useEffect 作用:你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它
//useEffect 会在每次渲染后都执行吗?第一次渲染之后和每次更新之后都会执行。每次我们重新渲染,都会生成新的 effect,替换掉之前的
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);
// 指定在该操作之后如何清除 effect:
return function cleanup() {//
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
//----------------------------------------------------------------------
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
// [count]前一次渲染的 [5] 和后一次渲染的 [5] 进行比较。因为数组中的所有元素都是相等的(5 === 5),React 会跳过这个 effect,这就实现了性能的优化。
//想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。
自定义HOOK
Hook 的每次调用都有一个完全独立的 state —— 因此你可以在单个组件中多次调用同一个自定义 Hook。
函数的名字以 “use
” 开头并调用其他 Hook,我们就说这是一个自定义 Hook
function useFriendStatus(friendID) {
//useState
和 useEffect
的 Hook 订阅一个好友的在线状态逻辑
}
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
在两个组件中使用相同的 Hook 会共享 state 吗?不会。自定义 Hook 是一种重用状态逻辑的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。
自定义 Hook 如何获取独立的 state?每次调用 Hook,它都会获取独立的 state。由于我们直接调用了 useFriendStatus
,从 React 的角度来看,我们的组件只是调用了 useState
和 useEffect
。 正如我们在之前章节中了解到的一样,我们可以在一个组件中多次调用 useState
和 useEffect
,它们是完全独立的。
4.,useContext 让你不使用组件嵌套就可以订阅 React 的 Context。
5.另外 useReducer 可以让你通过 reducer 来管理组件本地的复杂 state