这篇文章我将带着大家去初步了解下React hooks的一些知识。
我们会从以下三个方面去了解、介绍React hooks。
- 是什么?
- 为什么?
- 怎么做?
什么是Hooks?
总结起来就是hooks提供了在react函数组件中也可以使用类组件的state和生命周期的能力。
为什么要用Hooks?
组件嵌套问题
之前如果我们需要抽离一些重复的逻辑,就会选择 HOC 或者 render props 的方式。但是通过这样的方式去实现组件,你打开 React DevTools 就会发现组件被各种其他组件包裹在里面。这种方式首先提高了 debug 的难度,并且也很难实现共享状态。
但是通过 Hooks 的方式去抽离重复逻辑的话,一是不会增加组件的嵌套,二是可以实现状态的共享。
Class组件的问题
如果我们需要一个管理状态的组件,那么就必须使用 class 的方式去创建一个组件。但是一旦 class 组件变得复杂,那么四散的代码就很不容易维护。另外 class 组件通过 Babel 编译出来的代码也相比函数组件多得多。
Hooks 能够让我们通过函数组件的方式去管理状态,并且也能将四散的业务逻辑写成一个个 Hooks 便于复用以及维护。
怎么使用Hooks?
首先放两张Class Component 和React hooks两种不同方式的代码截图。
useState
useState 是其中最常有的钩子,可以为我们的函数组件提供local state,它接受一个初始state的值,返回一对变量。
const [count, setCount] = useState(0); // 0为state的初始值
setCount 用法是和 setState 一样的,可以传入一个新的状态或者函数。
setCount(prevCount => prevCount + 1)
useEffect
useEffect 即为生命周期的钩子。useEffect 可以让你在函数组件中执行副作用操作,相当于ComponentWiillMount、ComponentDidMount、ComponentWillUnmount三个生命周期的结合。有些副作用操作需要清除,所以需要返回一个函数。
useEffect 中还可以通过传入第二个参数来决定是否执行里面的操作来避免一些不必要的性能损失,只要第二个参数数组中的成员的值没有改变,就会跳过此次执行。如果传入一个空数组 [ ],那么该 effect 只会在组件 mount 和 unmount 时期执行。
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 如果count没有改变,就跳过此次执行
清除副作用操作可以在返回的函数中去进行。它会在前一次 effect执行后,下一次 effect 将要执行前,以及 Unmount 时期执行。
useRef
useRef 可以让我们去拿到最新的state。
const [count, setCount] = React.useState(0)
const ref = React.useRef(count)
React.useEffect(() => {
ref.current = count
setTimeout(() => {
console.log(ref.current) // 这里可以拿到更新后的state
}, 2000)
})
useRef 可以用来存储任何会改变的值,解决了在函数组件上不能通过实例去存储数据的问题。另外你还可以 useRef 来访问到改变之前的数据。
总结
- useState:传入我们所需的初始状态,返回一个常量状态以及改变状态的函数
- useEffect:第一个参数接受一个 callback,每次组件更新都会执行这个 callback,并且 callback 可以返回一个函数,该函数会在每次组件销毁前执行。如果 useEffect 内部有依赖外部的属性,并且希望依赖属性不改变就不重复执行 useEffect 的话,可以传入一个依赖数组作为第二个参数
- useRef:如果你需要有一个地方来存储变化的数据
更多的一些钩子大家可以去查询React相关文档去翻阅学习。附上文档地址。
React hooks为我们提供了react函数组件的一些扩展能力,分析了一些React hooks解决的问题以及简单的使用,我们完全可以使用React hooks去代替类组件,尽情拥抱React hooks。