React hooks 学习总结
/ / 点击 / 阅读耗时 7 分钟React hook 是16.8推出的新API,可以在不编写class的情况下使用state和其他特性。与无状态组件相比,hook函数组件提供了state以及处理副作用的API等等。
为什么要引入Hook?
在学习React hook之前,我很好奇为什么React团队为什么要引入hook,结合自己的理解以及从官网文档的描述,得出以下几点:
- 在组件之间复用状态逻辑很难:在没有hook之前,React只能通过 render props 和 高阶组件 来共享组件之间的状态逻辑,但是这两种方式都改变了组件结构,使得代码难以理解。
- 复杂组件变得难以理解: 组件常常在 componentDidMount 和 componentDidUpdate 中获取数据。但是,同一个 componentDidMount 中可能也包含很多其它的逻辑,如设置事件监听,而之后需在 componentWillUnmount 中清除。相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。
- 难以理解的class: 使用class创建组件比较麻烦的是在事件绑定上,this指向需要手动绑定,如果忘记的话很容易产生bug。
React hook中最重要的几个函数是以下几个:
- useState
- useEffect
useState
useState是很重要的一个hook函数,主要是用来创建组件内部数据,以及设置组件内部定义的数据。
import {useState} from 'react'
function countExample (props){
const [count,setCount] = useState(0)
return(
<button onClick={()=>SetCount(count+1)}>
<p>当前值为{count}</p>
)
}
useState函数可以接受一个参数,代表状态初始化的数据。它返回一个数组,数组的第0项是自定义初始值,第1项是设置这个初始值的方法。例如上面代码中,count代表一个自定义变量,初始值为0。当然这个变量可以由开发者自己定义名称,同理setCount也是由用户自定义,不过一般设置属性名称为在自定义属性名前面加set。
如果想要创建多个自定义属性值怎么办?
function Example(){
const [age, setAge] = useState(42);
const [name, setName] = useState('banana');
const [gender,setGender] = useState('男')
}
useEffect
useEffect函数主要是处理一些副作用(接口请求、DOM操控、清除定时器等等),实际上可以看做是class组件中componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
useEffect函数有两个参数:
- 第一个参数为副作用执行的回调函数,在回调函数里面主要处理一些副作用。
- 第二个参数为一个数组,如果第二个参数为空,那么在每一个state变化时,都会执行副作用。如果为空数组,那么就相当于两次执行对比数组里面的属性,发现两次都为空数组,则不会更新副作用。数组里面可以传自定义属性,根据实际业务需求来判断当哪个属性发生变化后,再执行相应的副作用。
import React, { useState, useEffect } from 'react'
import { message } from 'antd';
function Example() {
const [count, setCount] = useState(0)
useEffect(() => {
message.info(`当前count值为${count}`;)
},[count])
return (
<div >
<button onClick={() => setCount(count - 1)}>-</button>
{
<b>当前count值为:{count}</b>
}
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
除了以上执行componentDidMount,componentDidUpdate钩子外,useEffect函数里面可以通过返回一个函数来达到执行 componentWillUnmount 方法。
import React, { useState, useEffect } from 'react'
import { message } from 'antd';
function Modal({ visible }) {
useEffect(() => {
message.success('show box')
return () => {
message.info('hide box')
};
}, [visible])
return (
<div style={{ width: '200px', height: '200px', background: 'red' }}>
</div>
)
}
export default function Effect() {
const [visible, setVisible] = useState(true)
return (
<div >
<button onClick={() => setVisible(!visible)}>setBox</button>
{
visible && <Modal visible={visible}></Modal>
}
</div>
)
}
以上Modal子组件是根据父组件动态显示的,当Modal子组件卸载后会触发effect钩子函数里面的return函数,从而显示hide box。
全文完。