React Hooks是V16.8的新特性,是一个向后兼容的新特性(不会引入破坏性的改变)。
Hook是一种能够“侵入”React的函数组件的状态和生命周期特性的函数。Hook不能用在class
中,因为Hook的目的就是你能够抛弃class
来使用React
React提供了一些内嵌的Hooks,例如useState
。也可以创建自己的Hook,达到在不同的组件间复用有状态的行为。
引入的原因
实现比现有方案(HOC/Render Props)更优雅的代码复用,为纯组件引入状态,能够将组件划分为更细的粒度。
- 现有的React的状态组件复用方式(高阶组件、Render Props)有各自的问题, 而Hooks可以优雅的(不改变组件层次)实现代码复用
- Hooks可以将组件根据功能,将组件划分为更小的粒度,便于调试、测试和维护
- Hooks可以不使用
Class
来编写组件,提高代码性能,降低React的使用难度
Hooks的使用规定
(1)只在最顶层调用Hooks,不要在内部循环、条件语句或嵌套函数中调用Hooks(这是因为React是通过多个Hooks的调用顺序来确定多个useState
中状态变量的对应关系),如果想要有条件的运行一个useEffect
,可以将条件判断放在Hook内部
useEffect(function persistForm() {
// ? We're not breaking the first rule anymore
if (name !== '') {
localStorage.setItem('formData', name);
}
});
(2)只在React函数中调用Hooks,不在普通的JavaScript函数中调用
可以通过ESLint的eslint-plugin-react-hooks
插件来检查、规范Hooks的使用,避免不规范的使用而导致的bug。
安装:
npm install eslint-plugin-react-hooks -D
ESLint的配置文件:
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error"
}
}
将来这个插件会默认集成在Create React App和类似工具中。
内置Hooks
React提供了一系列内置Hooks,共分为两大类,基础Hook和附加Hook。
基础Hook包括:
useState
useEffect
useContext
附加Hook包括:
useReducer
useCallback
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue
useState
1 useState
- 基础用法
import { useState } from 'react';
const [count, setCount] = useState(0);
内置的useState
用来为纯组件添加状态变量和更新方法,可以认为是this.state
和this.setState
的简化版,以数组的形式获取状态变量,返回数组中的第一个项是一个状态,第二个是更新方法,useState
接受的参数是初始值。
当再次渲染时,React会在函数组件中获取count
的最新值,如果想要更新count
可以调用setCount
2 useState
- 手动合并
注意:useState
不会自动合并更新对象,所以需要手动进行合并,举个例子,在class组件中:
class Test extends React.Component {
state = { a: 1, b: 2, };
render() {
console.log(this.state);
return (
<div>
<button onClick={() => this.setState({ a: 100 })}>click</button>
</div>
);
}
}
点击按钮,setState
会自动将对象合并,打印结果是{a: 100, b: 2}
而在使用Hooks的组件中中:
function Test() {
const [state, setState] = useState({ a: 1, b: 2 });
console.log(state);
return (
<div>
<button onClick={() => setState({ a: 100 })}>click</button>
</div>
);
}
useState
在更新时不会将对象合并,所以打印的结果是{a: 100}
&#x