React hooks编码方式

新版本新特性解读

  • render支持返回数组和字符串
 return [<div>1</div>,<div>2</div>]
  • 错误边界捕获
  • 提升SSR渲染速度,支持流式渲染
  • 减少文件体积
  • 生命周期函数更新
1、由于异步渲染的改动,有可能会导致
componentWillMount,componentWillReceiveProps,componentWillUpdate执行,所以抛弃这三个生命周期函数

2、createContext不必一层层传递,可以指定数据共享范围
3、createRef
4、hooks开发方式更新

hooks出现的意义是什么

  • hooks之间状态独立,依赖独立的状态来更新
  • 让函数组件有了状态管理
  • 解决了组件树不直观、类组件难维护、逻辑不易复用的问题
  • react多了第二个参数,依赖特定的参数执行函数

学习hooks的意义是什么

  • 高效开发
  • 提高组件复用性
  • 提高逻辑复用性
  • 提升性能
  • 实现更复杂的功能

应用场景

  • 利用hooks取代生命周期函数
  • 让函数组件拥有状态
  • 组件辅助函数
  • 处理发送请求
  • 存取数据
  • 做好性能优化

useState

import React, { useState } from "react";
const [name, setName] = userState("");

useEffect(类似于componentDidMount)

import React, { useEffect } from "react"; 
useEffect(() => {
    //2、再执行外面的函数
    return () => {
        //1、执行一些销毁的内容,先执行
    }
},[])//第二个函数是依赖执行的参数列表,无其他列表只执行一次,否则依赖后面参数变化来执行

//执行实际是render之后

useLayoutEffect(类似于componentWillMount)

import React, { useLayoutEffect } from "react"; 
useLayoutEffect(() => {
    
},[])//dom更新完成之后执行操作,第二个函数是依赖执行的参数列表,无其他列表只执行一次,否则依赖后面参数变化来执行
// 比useEffect先执行


useMemo

import React, { useMemo } from "react"; 
const getDoubleNum = useMemo(() => {
console.log('getDoubleNum'); //跟随num改变,缓存2*num
return 2*num
},[num])

return <div onClick={() => {setAge(age+1)}}>这是一个函数组件num:{getDoubleNum}age:{age}</div>

useCallback

  const getDoubleNum = useCallback(() => {
    console.log('getDoubleNum');
    return 2*num
  },[num])

  return <div onClick={() => {setAge(age+1)}}>这是一个函数组件num:{getDoubleNum()}age:{age}</div>

useMemo跟useCallback对比

  • useMemo返回的是一个值
  • useCallback返回的是一个函数
  • useMemo缓存的是一个值,useCallback缓存的是一个函数
const getDoubleNum = useCallback(() => {
    console.log('getDoubleNum');
    return 'test'
  },[num])
  set.add(getDoubleAge)
  console.log(set.size);//一直是2,不递增。传到子组件不会带动子组件更新

  const getDoubleAge = useMemo( () => {
    return age * 2
  },[age])
  set.add(getDoubleAge)
  console.log(set.size);//每次递增传到子组件,会带动子组件依赖函数执行

useRef

保存计时器内容

  const timer = useRef()
  useEffect(() => {
    timer.current = setInterval(() => {
      setNum(num => num+1)
    },400)
  },[])
  useEffect(() => {
    if(num > 10) {
      console.log('超过10秒了');
      clearInterval(timer.current)
    }
  },[num])

useContent(带动子组件内容变化)

const Context = createContext(null)
function StateFunction () {
  const [num, setNum] = useState(1) 
  const [age, setAge] = useState(12) 

  return <div onClick={() => setNum(num + 1)}>
    这是一个函数组件num:{num}
    <Context.Provider value={{num,age}}>
      <Item1></Item1>
      <Item2></Item2>
    </Context.Provider>
  </div>
}

function Item1() {
  const num = useContext(Context);
  console.log('num',num);
  return <div>子组件{num.num+1}</div>
}
function Item2() {
  const num = useContext(Context);
  return <div>子组件{num.num +2}</div>
}
export default StateFunction;

useReducer

import React, { useState, useReducer} from "react";

const store = {
  num: 1
}

const reducer = (state, action) => {
  switch(action.type) {
    case "changeNum":
      return {
        ...state,
        num: action.num
      };
    default:
      return {
        ...state
      };
  }
}


function StateFunction () {
  const [state, dispatch] = useReducer(reducer,store);

  return <div onClick={() => dispatch({
    type: 'changeNum',
    num: 100
  })}>
    这是一个函数组件num:{state.num}
  </div>
}

export default StateFunction;

useImperativeHandle

是为了函数组件可以使用ref

import React, { forwardRef, useImperativeHandle, useEffect, useRef } from 'react'

const TestRef = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    open() {
      console.log("open")
    }
  }))
})

function App () {
  const ref = useRef()
  useEffect(() => {
    ref.current.open() //open
  },[])
  
  return(
    <>
      <div>石小阳</div>
      <TestRef ref={ref}></TestRef>
    </>
  )
}
export default App

自定义hooks使用

loadData.js:

import React, {useEffect, useState} from 'react'

 function useLoadData() {
  const [num, setNum] = useState(1);
  useEffect(() => {
    setTimeout(() => {
      setNum(2)
    },1000)
  },[])
  return [num,setNum]
}

export default useLoadData

使用方:

import useLoadData from './loadData.js';
function StateFunction () {
  // const [state, dispatch] = useReducer(reducer,store);
  const [num, setNum] = useLoadData();

  return <div>
    这是一个函数组件num:{num}
  </div>
}
export default StateFunction;

抽离useLocalReducer

useLocalReducer.js

import React, { useState, useReducer} from "react";
const store = {
  num: 1
}

const reducer = (state, action) => {
  switch(action.type) {
    case "changeNum":
      return {
        ...state,
        num: action.num
      };
    default:
      return {
        ...state
      };
  }
}

function useLocalReducer() {
  const [state, dispatch] = useReducer(reducer, store);
  return [state, dispatch]
}

export default useLocalReducer;

使用方:

import React, { useState, useReducer} from "react";
import useLocalReducer from './useLocalReducer'


function StateFunction () {
  // const [state, dispatch] = useReducer(reducer,store);
  const [state, dispatch] = useLocalReducer();

  return <div onClick={() => { dispatch({
    type: 'changeNum',
    num: 100
  })}}>
    这是一个函数组件num:{state.num}
  </div>
}

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

推荐阅读更多精彩内容

  • 前言 本文全面介绍了React Hooks的所有API概念、用法、丰富的demo以及部分底层原理。 实际上,Rea...
    南宫__阅读 3,579评论 0 6
  • 什么是 Hooks 以往,React 组件都是通过 class 的形式来编写,只有无状态组件才可以用函数来编写。H...
    Actoress阅读 1,094评论 0 0
  • React-Hooks 1. React-hooks是什么 我们先来看一下官网的解释: Hook 是 React ...
    Linyqs阅读 903评论 0 0
  • 使用React Hooks有什么优势? 什么是hookshook 是一些可以让你在函数组件里面钩入react st...
    Lyan_2ab3阅读 356评论 0 1
  • Hooks 是React的一次革命性升级,本文将对其优势和API进行比较全面的解析 为什么要有hooks 在没有h...
    smartzheng阅读 937评论 0 5