React Hooks
钩子是React 16.8版本中引入的新功能。它使您无需编写类即可使用状态和其他React功能。钩子是从功能组件"钩子" React状态和生命周期功能的功能。它在类内部不起作用。
钩子是向后兼容的,这意味着它不包含任何重大更改。另外,它不会取代您对React概念的了解。
何时使用钩子
如果您编写了一个函数组件,然后又想添加一些功能声明它,以前您可以通过将其转换为类来实现。但是,现在您可以通过在现有函数组件内部使用钩子来实现此目的。
钩子规则
钩子类似于JavaScript函数,但是您需要使用它们时,请遵循以下两个规则。钩子规则可确保组件中的所有有状态逻辑在其源代码中均可见。这些规则是:
1、仅在顶层调用Hooks
请勿在循环,条件或嵌套函数内部调用Hooks。钩子应始终在React函数的顶层使用。该规则确保每次渲染组件时都以相同的顺序调用Hook。
2、仅从React函数调用Hooks
您不能从常规JavaScript函数调用Hooks。相反,您可以从React函数组件中调用Hook。钩子也可以从自定义钩子中调用。
React钩子的先决条件
节点版本6或更高版本
NPM 5.2或更高版本
用于运行React App的创建React应用程序工具
React Hooks安装
要使用React Hooks,我们需要运行以下命令:
$ npm install react@16.8.0-alpha.1--save
$ npm install react-dom@16.8.0-alpha.1--save
以上命令将安装支持React Hooks的最新React和React-DOM alpha版本。确保 package.json 文件列出了React和React-DOM依赖项,如下所示。
"react": "^16.8.0-alpha.1",
"react-dom": "^16.8.0-alpha.1",
钩子状态
钩子状态是在React应用中声明状态的新方法。 Hook使用useState()功能组件来设置和检索状态。让我们通过以下示例了解Hook状态。
App.js
import React, { useState } from 'react';
function CountApp() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default CountApp;
输出:
在上面例如,useState是需要在函数组件内部调用以向其添加一些本地状态的Hook。 useState返回一对,其中第一个元素是当前状态值/初始值,第二个元素是允许我们更新它的函数。之后,我们将从事件处理程序或其他地方调用此函数。 useState与类中的this.setState相似。没有钩子的等效代码如下所示。
App.js
import React, { useState } from 'react';
class CountApp extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p><b>You clicked {this.state.count} times</b></p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
export default CountApp;
钩子效果
效果钩子允许我们在功能组件中执行副作用(动作)。它不使用类组件中可用的组件生命周期方法。换句话说,效果钩子等效于componentDidMount(),componentDidUpdate()和componentWillUnmount()生命周期方法。
副作用具有大多数Web应用程序需要执行的常见功能,例如:
更新DOM,
从服务器API获取和使用数据,
设置订阅等
通过以下示例让我们了解钩子效应。
import React, { useState, useEffect } from 'react';
function CounterExample() {
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>
);
}
export default CounterExample;
上面的代码基于上一个示例,具有一个新功能,我们将文档标题设置为自定义消息,包括单击次数。
输出:
在React组件中,有两种类型的副作用:
没有清理的效果
清理效果
不进行清理的效果
它用于useEffect,它不会阻止浏览器更新屏幕。它使应用程序响应速度更快。不需要清除效果的最常见示例是手动DOM突变,网络请求,日志记录等。
具有清除效果的效果
某些效果需要DOM更新后进行清理。例如,如果我们要建立对某个外部数据源的订阅,那么清理内存很重要,这样就不会引起内存泄漏。当组件卸载时,React执行内存清理。但是,我们知道,效果会为每种渲染方法运行,而不仅仅是一次。因此,React还可以在下次运行效果之前清除先前渲染中的效果。
自定义钩子
自定义钩子是JavaScript函数。自定义钩子的名称以" use"开头,可以调用其他钩子。定制的Hook就像常规函数一样,开头的" use"一词表明该函数遵循Hooks的规则。构建自定义钩子可以使您将组件逻辑提取到可重用的函数中。
在下面的示例中,让我们了解自定义钩子的工作原理。
import React, { useState, useEffect } from 'react';
const useDocumentTitle = title => {
useEffect(() => {
document.title = title;
}, [title])
}
function CustomCounter() {
const [count, setCount] = useState(0);
const incrementCount = () => setCount(count + 1);
useDocumentTitle(`You clicked ${count} times`);
// useEffect(() => {
// document.title = `You clicked ${count} times`
// });
return (
<div>
<p>You clicked {count} times</p>
<button onClick={incrementCount}>Click me</button>
</div>
)
}
export default CustomCounter;
在上面的代码段中,useDocumentTitle是一个自定义的Hook,它使用一个参数作为文本字符串,将其作为标题。在此钩子中,我们将调用useEffect钩子并设置标题(只要标题已更改)。第二个参数仅在其本地状态与我们传递的内容不同时才执行该检查并更新标题。
注意: 自定义的Hook是自然遵循Hooks设计的约定,而不是React功能。
内置钩子
在这里,我们描述了React中内置钩子的API。内置的钩子可以分为以下两个部分。
基本钩子
useState
useEffect
useContext
附加钩子
useReducer
useCallback
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue