一遍就能学会的 react hooks
介绍
react hooks
是 React 16.8
的新增特性。 它可以让我们在函数组件中使用 state
、生命周期以及其他 react
特性,而不仅限于 class
组件
react hooks
的出现,标示着 react
中不会在存在无状态组件了,只有类组件和函数组件
对比
存在即合理,hooks
也不例外,它的出现,就代表了它要解决一些 class
组件的缺陷或者不足,那么我们先来看看 class
组件有什么不足或者问题存在
根据网上的说法我总结出三点,当然每种问题都有其解决方案
问题 | 解决方案 | 缺点 |
---|---|---|
生命周期臃肿、逻辑耦合 | 无 | |
逻辑难以复用 | 通过继承解决 | 不支持多继承 |
通过hoc解决 | 会增加额外的组件嵌套,也会有一些性能影响 | |
渲染属性 | 同上、层级臃肿、性能影响 | |
class this 指向问题 |
匿名函数 | 每次都创建新的函数,子组件重复不必要渲染 |
bind |
需要写很多跟逻辑、状态无关的代码 |
而 hooks
对这些问题都有较好的解决方案
- 没有了
class,
自然就没有了this
指向问题 - 通过自定义
useEffect
来解决复用问题 - 通过使用
useEffect
来细分逻辑,减小出现逻辑臃肿的场景
当然,hooks
是一把双刃剑,用的好自己能够达到效果,用的不好反而会 降低开发效率和质量,那么我们接下来看看如用更好的使用 hooks
吧
具体使用
useState 的使用
简单例子
hooks
的能力,就是让我们在函数组件中使用 state
, 就是通过 useState
来实现的,我们来看一个简单的例子
function App () {
const [ count, setCount ] = useState(0)
return (
<div>
点击次数: {
count }
<button onClick={
() => {
setCount(count + 1)}}>点我</button>
</div>
)
}
useState
的使用非常简单,我们从 React
中拿到 useState
后,只需要在使用的地方直接调用 useState
函数就可以, useState
会返回一个数组,第一个值是我们的 state,
第二个值是一个函数,用来修改该 state
的,那么这里为什么叫 count
和 setCount
?一定要叫这个吗,这里使用了 es6
的解构赋值,所以你可以给它起任何名字,updateCount
, doCount
、any thing
,当然,为了编码规范,所以建议统一使用一种命名规范,尤其是第二个值
相同值
当我们在使用 useState
时,修改值时传入同样的值,我们的组件会重新渲染吗,例如这样
function App () {
const [ count, setCount ] = useState(0)
console.log('component render count')
return (
<div>
点击次数: {
count }
<button onClick={
() => {
setCount(count)}}>点我</button>
</div>
)
}
结果是不会,放心使用
useState 的默认值
useState
支持我们在调用的时候直接传入一个值,来指定 state
的默认值,比如这样 useState(0)
, useState({ a: 1 })
, useState([ 1, 2 ])
,还支持我们传入一个函数,来通过逻辑计算出默认值,比如这样
function App (props) {
const [ count, setCount ] = useState(() => {
return props.count || 0
})
return (
<div>
点击次数: {
count }
<button onClick={
() => {
setCount(count + 1)}}>点我</button>
</div>
)
}
这个时候,就有小伙伴问了,那我组件每渲染一次,useState
中的函数就会执行一边吗,浪费性能,其实不会,useState
中的函数只会执行一次,我们可以做个测试
function App (props) {
const [ count, setCount ] = useState(() => {
console.log('useState default value function is call')
return props.count || 0
})
return (
<div>
点击次数: {
count }
<button onClick={
() => {
setCount(count + 1)}}>点我</button>
</div>
)
}
结果是
setUseState 时获取上一轮的值
我们在使用 useState
的第二个参数时,我们想要获取上一轮该 state
的值的话,只需要在 useState
返回的第二个参数,也就是我们上面的例子中的 setCount
使用时,传入一个参数,该函数的参数就是上一轮的 state
的值
setCount((count => count + 1)
多个 useState 的情况
useState
我们不可能只使用一个,当我们使用多个 useState
的时候,那 react
是如何识别那个是哪个呢,其实很简单,它是靠第一次执行的顺序来记录的,就相当于每个组件存放useState
的地方是一个数组,每使用一个新的 useState
,就向数组中 push
一个 useState
,那么当然,当我们在运行时改变、添加、减少 useState
时,react
还能正常执行吗
function App (props) {
let count, setCount
let sum, setSum
if (count > 2) {
[ count, setCount ] = useState(0)
[ sum, setSum ] = useState(10)
} else {
[ sum, setSum ] = useState(10)
[ count, setCount ] = useState(0)
}
return (
<div>
点击次数: {
count }
总计:{
sum }
<button onClick={
() => {
setCount(count + 1); setSum(sum - 1)}}>点我</button>
<