1.什么是Hook?
Hook是React 16.8的新增属性。可以在不编写calss的情况下使用state以及其他的React特性
2.Hook优势?
其主要是为了解决一下几个常见问题:
- 在组件之间服用状态逻辑难
- 复杂组件变的难以理解
- class学习及js中this的工作方式
- 简化周期函数,避免重复代码
- …
Hook可以让我们无需学习浮躁的函数式和响应式编程,同时也遵循React的精神原则。
3.Hook和现有代码有冲突吗?
Hook可以和现有项目代码同时工作,可以渐进式的使用,并且React并没有计划移除class
4.举个例子
import React, {useState, useEffect} from 'react';
export default function Product(props) {
const [count, setCount] = useState(0);
return (
<div>
<p>click {count} times</p>
<button onClick={() => setCount(count + 1)}>click me</button>
</div>
)
}
可以发现没有class,没有state,没有setState,但是从react中导入了两个新的方法,useState和useEddect。首先介绍sueState方法:
useState允许我们在React函数组件中添加state的Hook。
在class中,我们通过在构造函数中设置state,例如:
import React from 'react';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
而在Hook里面,我们没有class,没有state,我们通过useState来声明state变量:
import React, { useState } from 'react';
function Example() {
// 声明一个叫 “count” 的 state 变量
const [count, setCount] = useState(0);
}
-
useState做了什么呢?
定义了一个“state变量”
-
useState需要哪些参数?
唯一的参数就是初始化的state值,如果要创建两个参数,调用两次useState()即可
-
useState返回了什么?
当前的state以及更新后的state,数组形式
-
读取state
class中
<p>You clicked {this.state.count} times</p>
Hook中
<p>You clicked {count} times</p>
class中
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
Hook中
<button onClick={() => setCount(count + 1)}>
Click me
</button>
Effect Hook可以执行函数组件中的副作用
import React, { useState, useEffect } from 'react';
function Example() {
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>
);
}
点击button 更新state,并且更新document的title,那我们的class如何写呢?
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
其实也不用这么复杂,这只不过为了介绍Hook而写的
import React from 'react';
export default class Product extends React.Component {
constructor(props) {
super(props);
this.state = {
count:0
}
}
render() {
return (
<div>
<button onClick={()=>this.setState({count:this.state.count+1},()=>{
document.title = this.state.count;
})}>click</button>
</div>
);
}
}
利用setState的第二个参数一样可以实现。就先看钩子函数的写法,可以发现我们需要在两个周期函数中编写重复代码,而用useEffect 一行完成,我们可以理解为useEffect ≈ (calss周期函数的componentDidMount,componentDidUpdate 和 componentWillUnmount)三个函数的组合。
-
useEffect做了什么呢?
在React组件渲染后执行某些操作,更新定义的变量
-
为什么在组件内部调用uesEffect?
将 useEffect 放在组件内部让我们可以在 effect 中直接访问 count state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存函数作用域中。Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。
-
useEffect会在每次渲染后都执行吗?
是的,默认情况下,它在第一次渲染之后和每次更新之后都会执行。
如何清除effect
calss中:
componentDidmount(){
xx.addEventListener()
}
componentWillUnmount(){
xx.addEventListener()
}
Hook中:
useEffect(()=>{
xx.addEventListener();
return ()=>xx.addEventListener()
})
这是effect 可选的清除机制。每个 effect 都可以返回一个清除函数。会在组件卸载的时候执行清除操作。
Hook规则
https://react.docschina.org/docs/hooks-rules.html
建议使用ESLint插件eslint-plugin-react-hooks 来强制执行某些规则。
Hook FAQ
https://react.docschina.org/docs/hooks-faq.html
–end