react之Hook用后总结

Hook

注意hook只能在函数组件中使用

useState()

作用:const res = useState(initState) 状态的改变
返回值:是一个array:[state, changeNum]
写法:const [ num, changeNum ] = useState(0)

import React,{useState} from 'react'

// console.log("useState=",useState)
/*
useState= ƒ useState(initialState) {
      var dispatcher = resolveDispatcher();
      return dispatcher.useState(initialState);
    }
*/

function UseState() {
  const [num, changeNum] = useState(0)
  return (
    <div>
      <div>{num}</div>
      <button onClick={() => {
        changeNum(num + 1)
      }}>点我数量加1{num}</button>
    </div>
  )
}
// 使用useState 实现了在函数组件中的状态改变
export default UseState

useEffect()

作用:实现类组件中生命周期的函数功能
用法:useEffect(callback, 依赖)

import React, { useEffect, useState } from 'react'
// console.log("useEffect=", useEffect)
/*
useEffect= ƒ useEffect(create, deps) {
      var dispatcher = resolveDispatcher();
      return dispatcher.useEffect(create, deps);
    }
*/

function UseEffect() {
  const [num, changeNum] = useState(0)
  const [qty, changeQty] = useState(1)

  // 注意:以下的useEffect 一进入页面初始化都会执行,但是必须等render渲染之后,可以根据后面的依赖和return后再执行

  // 1、没有指定依赖:实现componentDidMount 和 componentDidUpdate
  //    进入组件执行下面代码, 更新组件执行下面代码
  useEffect(function () {
    // 这里的代码在数据挂载后执行,在此可执行ajax请求,dom操作
    console.log('useEffect没有指定依赖')
  })

  // 2、指定空依赖:实现componentDidMount
  //    进入组件执行下面代码,后面就不再执行下面代码
  useEffect(function () {
    // 这里的代码在数据挂载后执行,在此可执行ajax请求,dom操作
    console.log('useEffect空依赖')
  }, [])

  // 3、指定某个依赖:实现shouldComponentUpdate的效果
  //    只有qty的 更新时,才执行这里的代码,不是qty更新,不执行下面代码
  useEffect(function () {
    // 这里的代码在数据挂载后执行,在此可执行ajax请求,dom操作
    console.log('useEffect的qtyChange')
  }, [qty])

  // 4、指定返回值: 实现componentWillUnmont 的效果
  useEffect(function () {
    // 进入组件先执行下面的代码,而return 后面的是在组件被销毁后执行
    console.log('useEffect,return返回值')

    return function () {
      // 这里的代码在组件被销毁后执行
      // 比如 取消ajax的请求,关闭定时器
      console.log('指定返回值,实现componentWillUnmont')
    }
  })

  return (
    <div>
      <h1>useEffect()</h1>
      <button onClick={() => {
        changeNum(num + 1)
      }
      }>点我num:{num} </button>
      <button onClick={() => {
        changeQty(qty + 1)
      }}>点我qty:{qty}</button>
    </div>
  )
}

  /*
    类组件的刷新只执行render
    函数组件会从头到尾执行一遍所有代码
      注意点: 函数组件必须等render渲染之后,才会执行上面的代码(根据生命周期图可知)useEffect(), dom节点这时也可以拿到
  */

export default UseEffect

useMemo()

作用:用来执行一些大量计算和花费大量时间的操作
用法:useMemo(callback, [xxx])

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

function UseMemo() {
  const [num, changeNum] = useState(1)
  const [qty, changeQty] = useState(1)
  
  // 当需要大量的计算时,用 useMemo 
  // 而num依赖 ,只有当num更新时,才执行下面代码
  const total = useMemo(function () {
    console.log('计算总和')
    let total = 0
    for (let i = 0; i < num * 10000; i++) {
      total += i
    }
    return total
  }, [num])

  return (
    <div>
      <h1>useMemo()</h1>
      总和:{total}
      <button onClick={() => {
        changeNum(num + 1)
      }}>num:{num}</button>
      <button onClick={() => {
        changeQty(qty + 1)
      }}>qty:{qty}</button>
    </div>
  )
}

export default UseMemo

useCallback()

用法:useCallback(callback, [xxx])

import React, {
  useCallback,
  useMemo,
  useState
} from 'react'

const callbackList = []

function UseCallback() {
  const [num, changeNum] = useState(1)
  const [qty, changeQty] = useState(1)


  const handleNum = useCallback(function () {
    changeNum(num + 1)
  }, [num])

  //下面的代码每次更新组件,会创建一个函数
  const handleQty = function () {
    changeQty(qty + 1)
  }

  callbackList.push(handleNum)

  console.log(callbackList, callbackList[0] === callbackList[1])

  // 使用useMemo 实现useCallback的功能
  // const handleNum = useMemo(function () {
  //   return function () {
  //     changeNum(num + 1)
  //   }
  // },[num])

  return (
    <div>
      useCallback()
      <button onClick={handleNum}>num:{num}</button>
      <button onClick={handleQty}>qty:{qty}</button>
    </div>
  )
}

/** 
 * 第一次点击 handleQty 时,打印的为true  
 * 说明handleNum 是从缓存里面拿的 handleNum 是用 useCallback 
 * 
 * 第二次点击 handleNum 时,打印的为false 
 * 说明每次更新组件,会创建一个函数,因为handleNum 发生变化
 * 
*/

export default UseCallback

useReducer()

作用:实现简单的reducer功能,在组件间实现数据共享
用法:const [state, dispatch] = useReducer(reducer, initState)

import React, { useCallback, useMemo, useReducer } from 'react'

const initState = [
  { name: "goods1", price: 98, qty: 2 },
  { name: "goods2", price: 198, qty: 2 },
  { name: "goods3", price: 998, qty: 1 },
]

function reducer(state, action) {
  switch (action.type) {
    case 'add':
      return [action.goods, ...state]
    case 'remove':
      return state.filter(item => item.name !== action.name)
    case 'changeQty':
      return state.map(item => {
        if (item.name === action.name) {
          item.qty = action.qty
        }
      })
    case 'clear':
      return []
    default:
      throw new Error('type error')
  }
}

function UseReducer() {
  const [state, dispatch] = useReducer(reducer, initState)
  
  const clearCart = useCallback(function () {
    const action = { type: 'clear' }
    dispatch(action)
  }, [])
  // 加空依赖:只执行一次

  const addToCart = useCallback(function (name) {
    // 判断是否存在
    // 存在:修改数量
    // 否则:添加商品
    // console.log("state",state.length)
    // 添加商品
    let action = { type: 'add', goods: { name: "goods" + (state.length + 1), price: 198, qty: 2 }, }
    dispatch(action)
  }, [state])
  // 加自定义依赖:当数据改变时,才更新

  // 计算总价 大量计算时使用 useMemo()
  const total = useMemo(() => {
    return state.reduce((prev, item) => prev + item.price * item.qty, 0)
  }, [state])
  // 加自定义依赖:当数据改变时,才更新

  // 删除商品
  const removeItem = useCallback(function (name) {
    const action = { type: 'remove', name }
    dispatch(action)
  }, [])
  // 加空依赖:只执行一次

  return (
    <div>
      <h1>useReducer()</h1>
      <ul>
        {
          state.map(item => <li key={item.name}>
            <h4>{item.name}</h4>
            <p className="price">{item.price}&times;{item.qty}</p>
            <button onClick={removeItem.bind(this, item.name)}>删除</button>
          </li>)
        }
      </ul>
      {/* <div style={{ textAlign: 'right' }}>总价:{total}</div> */}
      <button onClick={clearCart}>清空购物车</button>
      <button onClick={addToCart.bind(null, 'goods3')}>添加</button>
    </div>
  )
}

export default UseReducer

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值