react中hooks使用详解

useState

const [ count ,setCount] = useState(parameter)
  • count保存useState中的参数,参数可以为传入普通的参数,也可以传入function和array,在没有传入参数时为undefined
  • setCount在改变count中的值时使用
  • hook只能在React函数组件或者自定义hook中使用,不能在js函数中直接使用
  • useState最好不要在循环,条件判断或者子函数中调用,因为useState保存的数据使用链表的数据结构进行保存的,在上面的几种条件下使用useState会使链表断裂,数据会错乱
  • 在React钩子函数及合成事件中,表现为异步
  • 在setTimeout和setInterval及DOM原生事件中表现为同步

useEffect

useEffect(() => {
    console.log('开始订阅')
    return () => {
      console.log('取消订阅')
    }
  }, [count])
  • 主要用于模拟类组件中的生命周期,需要传入一个函数,在函数体类似类组件中componentDidmount函数,return返回的也是一个函数,类似于类组件中componentWillUnmount函数,我们可以在函数体中订阅某些事件,在return返回函数中取消订阅事件
  • hook是可以添加多个相同的hook函数,这就意味着不必像类组件中所有的订阅事件和网络请求都放到componentWillUnmount,可以使用相同的hook将不同的事件进行抽取
  • useEffect的第二个参数是一个数组,里面主要放函数体中的一些变量,当这些变量发生改变时,函数才会被重新执行,如果不希望依赖任何变量时,传入空的数组就行

useContext

在组件中使用共享的Context有两种方式
  • 类组件可以通过 类名.contextType = MyContext方式,在类中获取context
  • 多个Context或者在函数式组件中通过 MyContext.Consumer 方式共享context
  • 当存在多个context时的方式会存在大量的嵌套

Context Hook允许我们通过Hook来直接获取某个Context的值

 const maincontext = useContext(Maincontext)  // 直接获取传入的value值 
  //简化context获取值得操作,直接通过usecontext就可以获取到传入的value值
  //但是第一步操作仍然不能少
  const usecontext = useContext(Usecontext)
  console.log(maincontext, usecontext)

useReducer

  • useReducer主要用于在相同事件,不同方法时,代替useState,避免过多的useState方法
  • 要注意的是useReducer代替的是useState,不是redux,useReducer里面的状态是不能共享的
import React, { useState, useReducer } from 'react'

function reducer(state, action) {

  switch (action.type) {
    case "add":
      return { ...state, count: state.count + 1 };
    case "sub":
      return { ...state, count: state.count - 1 }
    default:
      return state
  }
}
export default function Home() {
  // const [count, setCount] = useState(0)
  const [state, dispatch] = useReducer(reducer, { count: 0 })  //拆分usestate
  //将改变state状态统一进行管理
  return (
    <div>
      <h2>当前计数:{state.count}</h2>
      <button onClick={e => dispatch({ type: "add" })}>+1</button>
      <button onClick={e => dispatch({ type: "sub" })}>+1</button>
    </div>
  )
}

useCallback 和 useMemo

  • 这两个的作用都是一样的,都是为了对子组件传递相同内容的函数或者对象时,让子组件不要重新进行渲染
  • 区别就是useCallback传入的是函数,可以添加相应的依赖项
 const sub = useCallback(     ///子组件在没有数据改变情况下不会重新渲染
    () => {
      console.log("sub被执行")
      setCount(count - 1)
    }, [count],
  )
  • useMemo返回的可以是对象,数组,函数,也可以添加相应的依赖
//返回的是对象
  const info = useMemo(() => {
    return { name: "jack", age: 18 };
  }, []);

useRef

常用的ref是两种用法

  • 用法一:引入DOM(或者组件,但是需要是class组件)元素
  • 用法二:保存一个数据,这个对象在整个生命周期中可以保存不变
import React, { useRef, useState, useEffect } from 'react'

export default function UseRefDemo1() {
  const divRef = useRef()
  const iptRef = useRef()
  const [count, setCount] = useState(0)
  const countRef = useRef(count)  //只能保持初始值,
  useEffect(() => {            //通过useEffect可以保存上一次的值
    countRef.current = count
  }, [count])
  function changeBtn() {
    divRef.current.innerHTML = "world"
    iptRef.current.focus()
  }
  return (
    <div>
      <div ref={divRef}>hello</div>
      <input ref={iptRef} type="" name="" id="" />
      <button onClick={e => changeBtn()}>点击</button>
      <h2  >CountRef:{countRef.current}</h2>
      <h2>count: {count}</h2>
      <button onClick={e => setCount(count + 1)}>+1</button>
    </div>
  )
}

useImperativeHandle

理解useImperativeHandle的用法先来看一下ref和forwardRef结合使用

  • 通过forwardRef可以将ref转发到子组件
  • 子组件拿到父组件中创建的ref,绑定到自己的某一个元素中
import React, { forwardRef, useRef, useImperativeHandle } from 'react'
//父组件通过ref建立联系,子组件通过forwardRef接收ref
const Btn = forwardRef((props, ref) => {
  const forwardRef = useRef()
  //下面需要利用子组件的ref
  return <input ref={forwardRef} type="text" />
})
export default function RefDemo() {
  const btnRef = useRef()
  return (
    <div>
      <Btn ref={btnRef} ></Btn>
      <button onClick={e => btnRef.current.focus()}>点击</button>
    </div>
  )
}
  • 这个例子就展示了ref和forwardRef的结合使用,看起来其实是,没有什么问题的,但是不够严谨,父组件不仅仅能拿到子组件的focus方法,还能拿到其他的方法,但是这里只需要focus方法,react为了能让代码更加严谨一点造出来一个useImperativeHandle方法,这个方法主要是让父组件只能拿到他想要的方法,其他不要的方法不需要暴露给子组件,下面对上面的代码进行一个更加严谨的写法
import React, { forwardRef, useRef, useImperativeHandle } from 'react'
//父组件通过ref建立联系,子组件通过forwardRef接收ref
//useImperativeHandle 作用只暴露父组件需要的子组件方法和属性
const Btn = forwardRef((props, ref) => {
  const forwardRef = useRef()
  useImperativeHandle(ref, () => ({
    focus: () => {    //父组件只需要focus方法,只暴露子组件focus方法
      forwardRef.current.focus();
    }
  }), [forwardRef.current])  //子组件的ref发生更新时重新渲染
  //下面需要利用子组件的ref
  return <input ref={forwardRef} type="text" />
})
export default function RefDemo() {
  const btnRef = useRef()
  return (
    <div>
      <Btn ref={btnRef} ></Btn>
      <button onClick={e => btnRef.current.focus()}>点击</button>
    </div>
  )
}

-这里子组件就只暴露了focus方法,其他的方法是没有暴露的,让代码的逻辑性更加严谨

useLayoutEffect

  • useLayoutEffect看起来和useEffect非常的相似,事实上他们也只有一点区别而已


    useLayoutEffect
  • useEffect会在渲染的内容更新到DOM上后执行,不会阻塞DOM的更新
  • useLayoutEffect会在渲染内容更新到DOM之前执行,会阻塞DOM的更新
  • 如果我们希望在某些操作发生之后再更新DOM,那么应该将这个操作放到useLayoutEffect
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • React Hooks 在了解React Hooks之前, 我们先看一下 Class 和函数式 的一般写法 Cla...
    YM雨蒙阅读 2,873评论 0 1
  • 1 关于hook 1.1 为什么使用hook 在react类组件(class)写法中,有setState和生命周期...
    江湖yi山人阅读 1,845评论 0 3
  • 一、前言 那一天我二十一岁,在我一生的黄金时代,我有好多奢望。我想爱,想吃,还想在一瞬间变成天上半明半暗的云,我觉...
    树街猫UP阅读 589评论 0 0
  • useState 1.基本使用 等价于 2. 复杂的state 3.使用状态 4. 注意事项 1). 如果stat...
    sweetBoy_9126阅读 3,017评论 0 6
  • 一、react新特性 1. context 在一个典型的 React 应用中,数据是通过 props 属性自上而下...
    zxhnext阅读 1,033评论 0 0