react笔记_07 hooks
创始人
2024-04-28 23:19:11
0

什么是hook?

以前我们称函数组件为简单组件,因为函数组件是无状态的(没有state)。

而在React 16.8版本增加了 Hook,它可以让你在不编写 class 组件的情况下,也就是我们可以在函数组件中使用 state 以及其他的 React 特性。

Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。

hook使用规则

  • 不要在循环,条件或嵌套函数中调用 Hook,确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。
  • 只在 React 函数中调用 Hook,不要在普通的 JavaScript 函数中调用 Hook。

useState

useState 是我们要学习的第一个 “Hook”。

举例说明

在这里插入图片描述
现在有如上需求:一个定时器 当点击 “点我num++” 按钮时,将num的值+1。

若是我们使用class组件如下

import React, { Component } from 'react'
export default class New extends Component {state = { num: 0 } // 初始化数据render() {const { num } = this.statereturn (
{num}
)}editNum = () =>{const { num } = this.statethis.setState({num: num+1}) // 通过setState更新数据} }

而在函数组件中,我们没有 this,所以我们不能分配或读取 this.state。我们直接在组件中调用 useState Hook.

import React, { useState } from 'react'
export default function New2 (){const [num, setNum] = useState(0) // 初始化数据const editNum = () =>{setNum(num+1) // 更新数据}  return(
{num}
) }

语法

1. 定义一个 state变量
  useState(initialState)

通过useState函数初始化数据

  • 参数:initialState为初始 state 值,不同于 class 的是,我们可以按照需要使用数字或字符串对其进行赋值,而不一定是对象。

  • 返回值:返回值为一个数组,数组中存在两个元素,第一个元素为当前state,第二个元素为更新此state的函数。

  • 该函数的作用是 定义一个 “state 变量”。这是一种在函数调用时保存变量的方式 。一般来说,在函数退出后变量就会”消失”,而 state 中的变量会被 React 保留

2. 读取state变量
const [num] = this.useState(0)console.log(num) // 使用时直接当作变量使用即可
3. 更新state变量值
const [num, numState] = this.useState(0)// numState是用于更新的函数
numState(value) // value可以为一个想要更新的值也可以是一个函数// 传入一个值 -> 该值作为更新值去进行更新
newState(1) // 会将num值变为1// 传入一个函数 ->  会自动调用该函数并将上一次的state值作为参数传入
newState(prestate => return prestate+1 ) // 会将num的值在当前基础上加1

如果新的 state 需要通过使用先前的 state 计算得出,对于同步更新来说 传值或者是函数是没有区别的,但是对于异步更新来说更推荐使用 函数,使用以下例子进行说明:

  • 参数为一个值
    import React, { useState } from 'react'
    export default function New2 (){const [num, setNum] = useState(0)const editNum = () =>{setTimeout(()=>{setNum(num+1)},1000)}  return(
    {num}
    ) }
  • 参数为一个函数
    import React, { useState } from 'react'
    export default function New2 (){const [num, setNum] = useState(0)const editNum = () =>{setTimeout(()=>{setNum(preState=> preState+1 )},1000)}  return(
    {num}
    ) }

当我设置为异步更新,点击按钮延迟到1s之后去更新数据,当我快速点击按钮时,也就是说在1s多次去触发更新,但是只有一次生效,因为 count 的值是没有变化的。

当使用函数式更新 state 的时候,这种问题就没有了,因为它可以获取之前的 state 值,也就是代码中的 preState 每次都是最新的值

useEffect

Effect Hook 可以让你在函数组件中执行副作用操作。

语法

import React, { useEffect } from 'react'
useEffect(()=>{// 逻辑代码
},[])
  • 第一个参数是一个函数
  • 第二个参数为一个数组(可省略)

执行时机

Every time your component renders, React will update the screen and then run the
code inside useEffect.

默认情况下 useEffect在每次render之后执行
若是不想每次render之后执行,可以接收第二个参数来控制跳过执行。

跳过 Effect
[1] 每次render之后执行

若是第二个参数不传,则useEffect将每次render之后都会执行,相当于omponentDidMount,componentDidUpdate两个生命周期函数。

useEffect(()=>{console.log('执行了')
})

上述代码在 每次render之后都会执行。

[2] 仅在挂载时执行

若是第二个参数传入一个空数组,则useEffect将仅在初始化时执行,相当于omponentDidMount。

useEffect(()=>{console.log('执行了')
},[])

上述代码仅仅在初始化时执行。

[3]仅当某个值变化时执行

若是第二个参数传入 带有元素的数组,则useEffect将仅在初始化元素的值发生变化时执行

useEffect(()=>{console.log('执行了')
},[num])

上述代码仅在初始化和num的值发生变化时执行。

useEffect(()=>{console.log('执行了')
},[num,value])

上述代码仅在初始化和 num或value值发生变化时执行。

注意
若是(第二个参数)数组元素中存在引用类型,就应该在第一个参数也就是执行的副作用函数中不要用setState相关的代码,否则容易引起死循环!

[4] 在组件卸载时执行

在useEffect的第一个参数中,若是存在return,则return的函数将会在组件卸载时执行

举例说明

useEffect(() => {window.a = 100;return ()=>{window.a = 0};
}, []);

上述代码在组件挂载时执行 代码window.a = 100; 在组件卸载时执行window.a = 0

现象- useEffect在初始化时会执行两次

在写项目时,发现初次渲染useEffect执行了两次,在网上搜了一下发现这是React18 新加的特性

  • 这是 React18 才新增的特性。
  • 仅在开发模式(“development”)下,且使用了严格模式(“Strict Mode”)下会触发; 生产环境(“production”)模式下和原来一样,仅执行一次。
  • 之所以执行两次,是为了模拟立即卸载组件和重新挂载组件。为了帮助开发者提前发现重复挂载可能会造成的 Bug。 同时,也是为了以后 React的新功能做铺垫 -> 未来会给 React 增加一个特性,允许 React 在保留状态的同时,能够做到仅仅对UI部分的添加和删除.让开发者能够提前习惯和适应,做到组件的卸载和重新挂载之后, 重复执行 useEffect的时候不会影响应用正常运行。

清除effect

有时候,我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志,这些都是常见的无需清除的操作。因为我们在执行完这些操作之后,就可以忽略他们了。还有一些副作用是需要清除的。例如订阅外部数据源。这种情况下,清除工作是非常重要的,可以防止引起内存泄露!

举例说明-清除事件监听

useEffect(() => {function handleScroll(e) {console.log(e.clientX, e.clientY);}window.addEventListener('scroll', handleScroll);return () => window.removeEventListener('scroll', handleScroll);
}, []);

参考文档

  • 官方文档
  • useState用法指南
  • 关于useEffect的第二个参数解读
  • React18的useEffect会执行两次

相关内容

热门资讯

德银:日元疲软是政策与资金共同... 德银最新报告指出,日元持续走弱的背后,是“政策默许”与“资本外流”共同作用的结果,短期内外汇干预的可...
ST名家汇(300506)披露... 截至2026年1月16日收盘,ST名家汇(300506)报收于4.16元,较前一交易日下跌0.72%...
衍生品交易迎政策规范,证监会对... 期货衍生品市场迎来政策规范,时隔两年多,证监会再就相关管理办法公开征求意见。 1月16日晚间,证监会...
【专家解读】2026年“两新”... 党的二十届四中全会提出,坚持扩大内需这个战略基点,坚持惠民生和促消费紧密结合,促进消费和投资、供给和...
国际观察丨“斩杀线”折射美国制... 新华社北京1月16日电 题:“斩杀线”折射美国制度弊端下的脆弱民生 新华社记者邓仙来 马倩 丛佳鑫 ...
涉及与供应商的合同纠纷房产被轮... 1月16日,金浦钛业(000545.SZ)公告称,全资子公司徐州钛白因涉及与供应商的合同纠纷,房产被...
乌政府调整宵禁政策 允许部分设... 当地时间16日,乌政府批准在宵禁期间允许购物中心、药店和加油站夜间营业,如果企业能发挥“不间断服务点...
公安部:敦促陈志犯罪集团在逃犯... 公安部今日发布《关于敦促陈志犯罪集团在逃犯罪嫌疑人投案自首的通告》。 近日,重大跨境赌诈犯罪集团头目...
出口退税取消政策影响渐显 一季... 中国有色金属工业协会硅业分会发布的数据显示,本周多晶硅N型复投料成交均价为5.92万元/吨,N型颗粒...
ST数源(000909)披露子... 截至2026年1月16日收盘,ST数源(000909)报收于5.41元,较前一交易日下跌0.55%,...