背景
近期React又出了一个新特性,由于现在还是alpha阶段,所以不建议引入自己的项目进行使用,官方文档介绍的有点过于详细了,我这里总结几点关键的,大家一起学习。
首先一句话概括他的作用:
不用引入class,还能使用state和React的其他特性。
引入他的原因也是升华React一直提倡的共用逻辑,重用组建中与状态相关的逻辑,并且方便开发维护。
React组件是支持两种方式的,一种是函数式一种是通过Class来声明的,由于函数式的使用方法确实很灵活,但是他不支持访问生命周期和state,只有一个props参数,所以使用起来局限性是很大的。
所以下面来看hooks是如何把状态加入到函数组件中的:
代码示例:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0); // 0是给count一个初始化的值,setCount是定义的改变count值的方法,count是当前的状态值
useEffect(() => {
document.title = `You clicked ${count} times`;
return function cleanup(){
document.title = 'you clicked 0 times';
}
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}> // 给setCount方法一个实现
Click me
</button>
</div>
);
}
这个例子很容易懂,类似于,userState方法返回一个数组,上面的写法是es6中的析构赋值。
state = {
count: 0
}
this.setState({count: count + 1})
而且useState是替换值而不是合并(merge)所以你可以一开始给一个变量设置为数组,而后替换为对象,这样更加灵活。
如果说useState解决了state的状态逻辑问题,那么useEffect就解决了生命周期的问题。
有些时候我们可能希望调用一些声明周期的函数来做一些事情,官方把他称为side effects,副作用一开始我还理解成了有害的操作,尴尬。其实就是生命周期中的一些触发方式,比如调用了render之后,就会触发componentDidUpdate
方法。在这里,useEffect相当于componentDidMount
、componentDidUpdate
、componentWillUnmount
这三个方法的合并。
为什么会有componentWillUnmount
?注意看这个useEffect返回了一个函数,这个函数在下一次effect执行之前或者unmount时期来执行,举个例子,我们在useEffect中使用了一个定时器,就可以在回调函数中将这个定时器给清除,这样无论是下次调用该方法,还是unmount的时期,都可以做到释放资源,当然了,如果不需要释放资源,这个return以及后面的函数就不需要写了,是可选的。
还有,这个useState
,useEffect
可以使用多组,而不是单单的一锤子买卖。
使用规则
hooks只能在顶层代码中使用,不可以在循环或者判断语句中使用,原因是渲染的时候react很依赖他们的顺序,如果执行过程中有一个未能正确执行,就会影响到后面的语句,要保证每次这几个都可以运行,众所周知,放在判断语句中不符合判断要求就不会执行。
实际应用:
hooks设计的初衷就是帮助我们提取有用的逻辑到一个可以重用的函数中。官方的实例就很好,提取了一个判断用户是否在线的逻辑,这个逻辑可以被应用到不同的组件中。
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
// ...
return isOnline;
}
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
就像这样,这个逻辑同样可以被应用到其他的组件中。
一些思考:
考虑到函数,输入和输出是两个关键因素。我们写函数的初衷就是为了提取一些公用的逻辑,还记得那些年我们收藏的工具函数嘛?比如输入年龄和体重返回一个是否超重的布尔值等等。这样一来理解可能稍微就清晰了一些,hooks在函数的基础上,可以让我们访问到state和对应组件的生命周期,实际上就是函数的加强版,一个真正能在react组件中使用的特殊函数。