react hook快速学习笔记

useState

用来声明状态变量,括号里面参数为初始值。

const [ count , setCount ] = useState(0);

useEffect&&useLayoutEffect

注意点:异步执行
副作用钩子,useLayoutEffect和原来componentDidMount&componentDidUpdate一致,在react完成DOM更新后马上同步调用的代码(DOM修改后且浏览器渲染之前),会阻塞页面渲染。而useEffect是会在整个页面渲染完才会调用的代码。

//首次渲染,和count更新都会再次执行
  const mounting = useRef(true);
  useEffect(() => {
    console.log('挂载componentDidmount')
    // 模拟componentDidUpdate生命周期,而去掉初次渲染时调用的 componentDidMount
    if (mounting.current) {
      console.log("初次")
      mounting.current = false;
      return 
    } 
    // 卸载componentWillUnmount
    return () => {
      console.log('卸载componentWillUnmount')
    }
  }, [])
第二个参数传值情况:
  1. 不传 每次渲染后都执行清理或者执行effect,容易死循环。
  2. 传 [], 只运行一次的 effect(仅在组件挂载和卸载时执行),componentDidmount
  3. 传普通变量的数组[id,name],当id或者name变化时候会执行,componentDidUpdate;传对象 [{}],因为js中{}==={}为false,会死循环

可代替

  1. componentDidMount
    • useEffect第二个参数[]时
  2. componentDidUpdate
    • useEffect第二个参数[count]时,即只有count变化时候才会调用
  3. componentWillUnmount
    操作方式:return一个匿名函数
useEffect(()=>{
    console.log('index页面')
    return ()=>{
      console.log('离开index页面')
    }
  },[])

useContext

解决传值问题(context上下文),可祖孙级别传值,可实时监听能动态变化
useContent的参数一般是由createContext的创建,通过 CountContext.Provider 包裹的组件,才能通过 useContext 获取对应的值
不用hook方式

import React, {createContext} from 'react';

const ChildContext = createContext(20); //括号里可以传默认值

function Child() {
  return (
    <ChildContext.Consumer>
      {/* 必须用函数返回 */}
      {
        val => <h1>值:{val}</h1>
      }
    </ChildContext.Consumer>
  )
}

function LazyDemo() {
  return (
    <div className="App">
      <ChildContext.Provider value={60}>
          <Child></Child>
      </ChildContext.Provider>
    </div>
  );
}

export default LazyDemo;

hook方式

import React, { useState, createContext, useContext } from 'react';
// 子组件传值
const CountContext = createContext();

function Counter(){
  let count = useContext(CountContext)
  return (<h2>{count}</h2>)
}

function Example(){
  const [count, setCount ] = useState(0) 
  return(
    <div>
      <p>{count}</p>
      <button onClick={()=>{setCount(count+1)}}>Click me</button>
      <CountContext.Provider value={count}>
          <Counter/>
      </CountContext.Provider>
    </div>
  )
}
 
export default Example;

useReducer 状态管理

  • state:更新后的state值
  • dispatch:可以理解为和useState的setState一样的效果
  • reducer:可以理解为redux的reducer
  • initialArg:初始值
  • init:惰性初始化
import React, { useReducer} from 'react';
// useReducer
// 第一个值  (函数,第二个值初始值)
// 通过dispatch去更新值

function ReducerDemo(){
  const [count, dispatch] = useReducer((state,action)=>{
    switch(action){
      case 'add':
        return state + 1
      case 'sub':
        return state - 1
      default:
        return state 
    }
  },0)

  return(
    <div>
      <h2>现在的分数是{count}</h2>
      <button onClick={()=>{dispatch('add')}}>Increment</button>
      <button onClick={()=>{dispatch('sub')}}>Decrement</button>
    </div>
  )
}

export default ReducerDemo

可结合useContext实现redux,主要就是吧dispacth放在Provider中value中传递给子组件,让子组件可以使用dispacth

export const Color = props=>{

  const [color, dispatch] = useReducer(reducer,'blue')

  return (
    <ColorContext.Provider value={{color,dispatch}}>
      {props.children}
    </ColorContext.Provider>
  )
}

useRef

  • 存放一些会发生变化的值,useRef 并不再单单是为了 DOM 的 ref 准备的,同时也会用来存放组件实例的属性。
  const inputEl = useRef(null)
  const [text, setText] = useState('哇哦')

  const onButtonClick = ()=> {
    inputEl.current.value = text
    console.log(inputEl)
  }

  return (
    <div>
      <input ref={inputEl} type="text"></input>
      <button onClick={onButtonClick}>展示文字</button>
    </div>
  )
  • 存变量

因为在函数式组件里没有了 this 来存放一些实例的变量,所以 React 建议使用 useRef 来存放一些会发生变化的值,useRef 并不再单单是为了 DOM 的 ref 准备的,同时也会用来存放组件实例的属性。

function Timer() {
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      // 定时器
    });
    intervalRef.current = id;
    // unmount时候清除定时器
    return () => {
      clearInterval(intervalRef.current);
    };
  });
}

useMemo 解决性能问题(缓存值)

如果说类组件的性能优化的方法是 shouldComponentUpdate 和 PureComponent,那么给函数组件做性能优化的就是这个 useMemo。

解决问题: 父组件传入一个值变化,导致子组件其他值也跟着重新渲染

//参数一:接受一个方法  
//参数2: 数组  [状态]   只有这个状态变动   才会调用 前面的方法,,,   写请求用
  const actionProcess1 = useMemo(()=>{
    function changeProcess1(){
      console.log('进程1动了')
      return name+',进程1来了'
    }
    changeProcess1(name)
  },[name])

useCallback解决性能问题(缓存方法)

useCallback 的作用在于利用 memoize 减少无效的 re-render,来达到性能优化的作用。缓存一个函数,常用于给子组件传递方法,避免不必要的更新,更多搭配React.Memo使用。

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

// 自定义hooks,用use开头命名,封装重复使用的代码,可以抽离出成一个模块,在多个场景下使用,提高代码的复用性

function useWinSize(){
	//设置变量size:{}
  const [size, setSize] = useState({
    width:document.documentElement.clientWidth,
    height:document.documentElement.clientHeight
  })

  // useCallback缓存方法  [] 只执行一次

  const onResize = useCallback(()=>{
    setSize({
      width:document.documentElement.clientWidth,
      height:document.documentElement.clientHeight,
    })
  },[])

  useEffect(()=>{
    
    window.addEventListener('resize',onResize)
    // // 销毁时
    return ()=>{
      window.removeEventListener('resize',onResize)
    }
  },[onResize])
  return size
}

function Example(){
  const size = useWinSize()
  return (
    <div>页面大小{size.width}*{size.height}</div>
  )
}

export default Example

注意:当useEffect里面使用了外部的变量的情况下,需要在第二个数组参数中放入对应的变量,防止类似 React Hook useLayoutEffect has a missing dependency: ‘options’. Either include it or remove the dependency array react-hooks/exhaustive-deps 的一些检查提示、代码规范.

useMemo和useCallback

useMemouseCallback接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于useMemo返回的是函数运行的结果,useCallback返回的是函数

useCallback(fn, inputs) === useMemo(() => fn, inputs))

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值