热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

React学习笔记6:ReactHooksAPI总结

useState-保存状态(惰性初始化)作用函数组件添加状态注意事项初始化以及更新state用来声明状态变量使用步骤(使用useStat

useState-保存状态(惰性初始化)


  • 作用
    • 函数组件添加状态
  • 注意事项
    • 初始化以及更新state
    • 用来声明状态变量
  • 使用步骤(使用useState来创建状态)
    1. 引入import React,{useState} from "react"
    2. 接收一个参数作为初始值
    3. 返回一个数组,第一个值为状态,第二个为改变状态的函数

useEffect-解决副效应

只要是副效应,都可以使用useEffect()引入。

useEffect,就是执行有副作用的操作,默认情况下,它在第一次渲染之后和每次更新之后都会执行。 可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount这三个函数的组合。


  • 作用/用途

    • 给没有生命周期的组件,添加结束渲染的信号
    • 获取数据
    • 事件监听或订阅
    • 改变DOM
    • 输出日志
  • 注意事项

    • 在render之后执行
    • 使用useEffect()时,如果有多个副效应,应该调用多个useEffect(),而不应该合并写在一起。
  • 使用步骤

    1. 引入import React,{useEffect} from "react"
    2. 接收一个函数作为参数
    3. 接收第二个参数(依赖列表),只有依赖更新时,才会执行函数
    4. 返回一个函数。先执行返回函数,再执行参数函数
  • 示例

    import React, { useState, useEffect } from &#39;react&#39;function EffectFunction() {const [num, setNum] &#61; useState(1)//以下函数先输出1&#xff0c;再输出2useEffect(() &#61;> {console.log("2")document.body.addEventListener(&#39;todo&#39;, () &#61;> { })return () &#61;> {document.body.removeEventListener(&#39;todo&#39;, () &#61;> { })console.log("1")}}, [num])return (<div onClick&#61;{() &#61;> setNum(num &#61;> num &#43; 1)}>这是一个函数组件-{num}</div>)
    }
    export default EffectFunction


useLayoutEffect-监测DOM


  • 作用

    • dom更新完成后执行某个操作
  • 注意事项

    • 有dom操作的副效应hooks
    • 在dom更新之后执行
  • 使用步骤

    1. 引入import React,{useLayoutEffect} from "react"
    2. 接收一个函数作为参数
    3. 接收第二个参数&#xff08;依赖列表&#xff09;&#xff0c;只有依赖更新时&#xff0c;才会执行函数
    4. 返回一个函数。先执行返回函数&#xff0c;再执行参数函数
  • 示例

    import React, { useState, useEffect, useLayoutEffect } from &#39;react&#39;function EffectFunction() {const [num, setNum] &#61; useState(1)useLayoutEffect(() &#61;> {console.log("useLayoutEffect")document.body.addEventListener(&#39;layout&#39;, () &#61;> { })return () &#61;> {document.body.removeEventListener(&#39;layout&#39;, () &#61;> { })}}, [num])useEffect(() &#61;> {console.log("useEffect")document.body.addEventListener(&#39;todo&#39;, () &#61;> { })return () &#61;> {document.body.removeEventListener(&#39;todo&#39;, () &#61;> { })}}, [num])return (<div onClick&#61;{() &#61;> setNum(num &#61;> num &#43; 1)}>这是一个函数组件-{num}</div>)}export default EffectFunction

  • useEffect与useLayoutEffect区别

    • useEffect执行时机在render之后
    • useLayoutEffect是在dom更新之后

useMemo-组件跟随状态更新


  • 概述

    当父组件因为自身状态改变而重新渲染时&#xff0c;会带动子组件的重新渲染&#xff0c;及时此时子组件的状态并没有发生改变&#xff0c;为了解决子组件的非必要渲染&#xff0c;可以使用memo函数来包装子组件&#xff0c;这样当子组件的props没有发生改变时&#xff0c;及时父组件重新渲染了&#xff0c;子组件也不会重新渲染。

  • 作用

    • 让组件中的函数跟随状态更新
  • 注意事项

    • 优化函数组件中的功能函数
  • 使用步骤

    1. 引入import React,{useMemo} from "react"
    2. 接收一个函数作为参数
    3. 接收第二个参数&#xff08;依赖列表&#xff09;&#xff0c;只有依赖更新时&#xff0c;才会执行函数
    4. 返回的是一个数值
  • 适用场景

    • 有些计算开销很大&#xff0c;就需要「记住」它的返回值&#xff0c;避免每次render都去重新计算。
    • 由于值的引用发生变化&#xff0c;导致下游组件重新渲染&#xff0c;也需要「记住」这个值。
  • 示例

    import React, { useState, useEffect, useMemo } from &#39;react&#39;function EffectFunction() {const [num, setNum] &#61; useState(1)const [age, setAge] &#61; useState(18)// function getDoubleNum(){// console.log("获取双倍的num")// return 2 * num// }//useMemo使用方法//1.接收一个函数作为参数//2.第二个参数为依赖列表//3.返回的是一个数值const getDoubleNum &#61; useMemo(()&#61;>{console.log("获取双倍的num")return 2*num},[num])return (<div onClick&#61;{() &#61;> setNum(num &#61;> num &#43; 1)}>这是一个函数组件-{getDoubleNum},age的值为----{age}</div>)
    }export default EffectFunction


useCallback-组件跟随状态更新


  • 作用
    • 跟随状态更新执行
  • 注意事项
    • 只有依赖项改变的时候才会执行
  • 使用场景
    • 在组件内部&#xff0c;那些会成为其他useEffect依赖项的方法&#xff0c;建议用 useCallback 包裹&#xff0c;或者直接编写在引用它的useEffect中 这种情况通常出现在reset等等这些函数&#xff0c;可能还有多个地方调用这个函数。
    • 如果你的function会作为props传递给子组件&#xff0c;请一定要使用 useCallback 包裹&#xff0c;对于子组件来说&#xff0c;如果每次render都会导致你传递的函数发生变化&#xff0c;可能会对它造成非常大的困扰。同时也不利于react做渲染优化。

useRef-长久保存数据


  • 概述

    • useRef返回的 ref 对象在组件的整个生命周期内保持不变&#xff0c;也就是说每次重新渲染函数组件时&#xff0c;返回的ref 对象都是同一个。从概念上讲&#xff0c;可以认为 refs 就像是一个 class 的实例变量。
      -useRef不仅仅是用来管理DOM ref的它可以存放任何变量&#xff0c;更改.current属性不会导致重新渲染。
  • 作用

    • 长久保存数据
  • 注意事项

    • 返回一个子元素索引&#xff0c;此索引在整个生命周期中保持不变
    • 对象发生改变&#xff0c;不通知。属性变更不重新渲染
  • 使用场景

    • 希望一个变量在这个组件中&#xff0c;即使组建重新渲染&#xff0c;这个值也不会变。
    • 保存子组件提供的某一个值&#xff08;可能是一个DOM元素&#xff0c;也可能就是一个普通对象&#xff09;
  • 示例

    import React, { useState, useEffect, useRef } from &#39;react&#39;function EffectFunction() {const [num, setNum] &#61; useState(1)const ref &#61; useRef()//1.保存一个值&#xff0c;在整个生命周期中维持不变//2.重新赋值ref.current不会触发重新渲染useEffect(() &#61;> {ref.current &#61; setInterval(() &#61;> {setNum(num &#61;> num &#43; 1)}, 400)}, [])useEffect(() &#61;> {if (num > 10) {console.log("超过10了", ref.current)clearInterval(ref.current)}}, [num])return (<div>这是一个函数组件-{num}</div>)
    }export default EffectFunction


useContext-组件之间共享状态


  • 作用

    • 带着子组件去更新&#xff08;游荡或者流浪&#xff09;
  • 注意事项

    • 上层数据发生改变&#xff0c;肯定会触发重新渲染
    • 当 Provider 的 value 值发生变化时&#xff0c;它内部的所有消费组件都会重新渲染
    • react 中数据是通过 props 属性自上而下&#xff08;由父及子&#xff09;进行传递的&#xff0c;但这种做法对于多层级父子关系的组件传值是极其繁琐的。react 提供了context api 来实现在组件之间共享此类值的方式&#xff0c;而不必显式地通过组件树的逐层传递 props。React 16.3之后的contextapi 较之前的好用
    • Context.Provider&#xff0c;接收一个 value 属性&#xff0c;传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用&#xff0c;里层的会覆盖外层的数据
  • 使用步骤&#xff08;单数据源、父组件向子组件通信&#xff09;

    1. 需要引入useContextcreateContext两个内容
    2. 通过createContext创建一个context句柄
    3. Context.Provider来确定数据共享范围
    4. 通过value来分发内容
    5. 在子组件中&#xff0c;通过useContext(context句柄)来获取数据
  • 使用Context.Provider&#xff0c;具体使用方法如下&#xff1a;

    1. 使用 createContext() 创建一个context 对象&#xff08;内容为需要传递的数据&#xff09;&#xff0c;参数为默认值&#xff1b;
    2. 在父组件外层使用 <.Provider> 将当前 context 的值传递给内部所有的组件树。当使用了 <.Provider> 后&#xff0c;不再读取上面的默认值&#xff0c;需要设置 value 属性来进行数据传递。
    3. 当组件需要读取数据时&#xff0c;指定 contextType 读取当前的 context 对象&#xff08;即刚开始创建的 context&#xff09;&#xff1b;
    4. 通过useContext(context句柄)&#xff0c;获取到当前 context 内的数据
  • 示例

    import React, { useState, useContext, createContext } from &#39;react&#39;//1.需要引入useContext、createContext两个内容
    //2.通过createContext创建一个context句柄
    //3.Conext.Provider来确定数据共享范围
    //4.通过value来分发内容
    //5.在子组件中&#xff0c;通过useContext(context句柄)来获取数据const ShowNumContext &#61; createContext(null)
    function EffectFunction() {const [num, setNum] &#61; useState(1)return (<div>这是一个函数组件-{num}// 使用Provider 将当前context的值传递给下面的组件树<ShowNumContext.Provider value&#61;{num}><Item1></Item1><Item2></Item2></ShowNumContext.Provider></div>)
    }
    /*** 子组件1*/
    function Item1() {//指定contextType 读取当前的context//react 会往上找到最近的 Provider&#xff0c;然后使用它的值const num &#61; useContext(ShowNumContext)return (<div>子组件{num}</div>)
    }/*** 子组件2*/
    function Item2() {const num &#61; useContext(ShowNumContext)return (<div>子组件{num &#43; 2}</div>)
    }export default EffectFunction

上面的方法中&#xff0c;我们实现了跨组件的数据传递&#xff0c;这种方式的缺点是只能有一个共享的数据源&#xff0c;也就是在 Item1 组件Item2组件中&#xff0c;指定 num的值只能是一个。那么如果我们有多个数据源都需要进行跨组件传递&#xff0c;应该怎么做呢&#xff1f;可以使用 <.Consumer> 来实现对多个数据源进行共享&#xff08;多数据源跨组件通信&#xff09;


  • Context的使用场景

    Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。谨慎使用&#xff0c;因为这会使得组件的复用性变差。如果用组件组合可以解决的问题&#xff0c;就不要使用 Context 。

    使用 context 的通用的场景包括管理当前的 locale&#xff0c;theme&#xff0c;或者一些缓存数据。


useReducer-复杂逻辑简单化


  • 作用

    • 去其他地方借用资源
  • 使用步骤

    1. 需要创建数据仓库store管理者reducer
    2. 通过useReducer(reducer,store)来获取state和dispatch
  • 注意事项

    • 函数组件的redux的操作
  • 示例

    import React, { useReducer } from &#39;react&#39;//redux必须的内容——store&#xff0c;reducer//useReducer使用方法
    //1.需要创建 数据仓库store和管理者reducer
    //2.通过useReducer(reducer,store)来获取state和dispatch
    const store &#61; {num: 10
    }
    const reducer &#61; (state, action) &#61;> {switch (action.type) {case "changeNum":return {...state,num: action.num}default:return {...state}}
    }
    function EffectFunction() {const [state, dispatch] &#61; useReducer(reducer, store)return (<div onClick&#61;{() &#61;> {dispatch({type: &#39;changeNum&#39;,num: 100})}}>这是一个函数组件-{state.num}</div>)
    }
    export default EffectFunction


自定义Hooks


  • 作用

    • 自定义Hooks以支持特殊场景
  • 使用步骤

    1. 引入react和自己需要的hook
    2. 创建自己的hook函数
    3. 返回一个数组&#xff0c;数组中第一个内容是数据&#xff0c;第二个是修改数据的函数
    4. 将自己定义的hook函数暴露出去
    5. 在自己的业务组件中&#xff0c;引入并使用
  • 示例

    import React, { useState, useEffect } from &#39;react&#39;
    /*** 自定义Hooks步骤* 1.引入react和自己需要的hook* 2.创建自己的hook函数* 3.返回一个数组&#xff0c;数组中第一个内容是数据&#xff0c;第二个是修改数据的函数* 4.将自己定义的hook函数暴露出去* 5.在自己的业务组件中&#xff0c;引入并使用*///如何实现模拟的数据接口请求功能
    function userLoadData() {const [num, setNum] &#61; useState(1)useEffect(() &#61;> {setTimeout(() &#61;> {setNum(2)}, 1000)}, [])return [num,setNum]
    }
    export default userLoadData


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • React基础篇一 - JSX语法扩展与使用
    本文介绍了React基础篇一中的JSX语法扩展与使用。JSX是一种JavaScript的语法扩展,用于描述React中的用户界面。文章详细介绍了在JSX中使用表达式的方法,并给出了一个示例代码。最后,提到了JSX在编译后会被转化为普通的JavaScript对象。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文介绍了如何使用elementui分页组件进行分页功能的改写,只需一行代码即可调用。通过封装分页组件,避免在每个页面都写跳转请求的重复代码。详细的代码示例和使用方法在正文中给出。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
author-avatar
情人節快樂1991的名单
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有