React Hook (2)

上一篇介绍了基础的 Hooks,这一篇接着上一篇介绍下额外的 Hooks.
React Hooks

1. useRef 获取 DOM 的节点或节点内容
const refContainer = useRef(initialValue);

用法:

  • 使用用 ref 引用一个值
  • 通过 ref 操作 DOM
  • 避免重复创建 ref 的内容

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

import React, { createRef, useRef } from 'react'
export default function UseRef() {
    const inputRef = useRef<any>()
    const getFocus = () => {
        inputRef.current.focus()
        console.log(inputRef.current)
        console.log(inputRef.current.value)
    }
  return (
    <>
        <input type="text" ref={inputRef} />
        <button onClick={getFocus}>获取焦点</button>
    </>
  )
}

问题:无法获取自定义组件的ref

const inputRef = useRef(null);
return <MyInput ref={inputRef} />;

默认情况下,自定义组件不会暴露它们内部 DOM 节点的 ref。
想要 暴露其 DOM 节点的组件必须选择该行为。一个组件可以指定将它的 ref “转发”给一个子组件。
解决:将自定义组件包裹在forwardRef中然后再使用

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});
import { forwardRef } from 'react';
const MyInput = forwardRef(({ value, onChange }, ref) => {
  return (
    <input
      value={value}
      onChange={onChange}
      ref={ref}
    />
  );
});

export default MyInput;

最后,父级组件就可以得到它的 ref。

2. useCallback 缓存一个函数,当依赖项发生改变的时候触发回调函数

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
)
import React, { useState, useCallback } from 'react'
export default function UseCallback():any {
    const [count, setCount] = useState<number>(1)
    const addNum = () => {
        setCount(() => count + 1)
    }
    const addCallback = useCallback((): void => {
        console.log('count改变了:', count)
    },[count])
    return (
        <>
         <h2>count的值为:{ count }</h2>
         <button onClick={addNum}>Btn1</button>
         {/* <button onClick={addCallback}>Btn2</button> */}
        </>
    )
}
3. useMemo 用来缓存一个值或者计算结果,可以用来做性能优化
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
import React from 'react'
import {useState, useMemo} from 'react'
import UseEffect from './UseEffect'

export default function UseMemo () {
    // useMemo的作用是缓存一个值或者计算结果,当值或结果发生改变的时候,重新计算。
    // 可以理解为vue中的computed就算属性
    const [count, setCount] = useState<number>(1)   
    const [count2, setCount2] = useState<number>(1)
    // const result = () => count * count
    // 缓存这个计算结果,当依赖项count2发生改变的时候 result的结果重新计算
    // 注意:依赖项[count2]是包含在数组中的,意思是可以有多个依赖项
    const result: number = useMemo(():any => count * count, [count2])
  return (
    <div>  
      <h1>我是useMemo组件</h1>
      <h2>count: {count}</h2>
      <h2>count2: {count2}</h2>
      <h1>result的结果:{result}</h1>
      <button onClick={() => setCount(count + 1)}>count +</button>
      <button onClick={() => setCount2(count2 + 1)}>count2 +</button>
  </div>
  )
}
4. useReducer
  • useReducer来操作更多的自变量,相当于多个useState
  • useState 的替代方案
  • 它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法
const [state, dispatch] = useReducer(reducer, initialArg, init);
import React, {useState, useReducer} from 'react'
export default function UseReducer() {
/**
 * 在使用useReducer的时候,需要传递2个参数
    第一个是reducer的function, 第二个是初始化数据
    它和redux中的数据流很相似,如果要改变数据只能通过dispatch派发一个action
    const [state, dispatch] = useReducer(reducer, initialState)
   它接受reducer函数和状态的初始值作为参数,返回一个数组,其中第一项为当前的状态值,第二项为发送action的dispatch函数
 */
 
    // 申明一个 reducer 方法
    const reducer = (state: any, action: any): any =>{
        switch (action.type) {
            case 'increment':
                return { ...state, count: state.count + 1 }
            case 'decrement':
                return { ...state, count: state.count - 1 }
            default:
                return state
        }
    }
    const [state, dispatch] = useReducer(reducer, {
        count: 1,
        name: 'Reducer Demo',
        list: ['Apple', 'Banana', 'Mango']
    })
  return (
   <>
    <h2>UseReducer</h2>
    <button onClick={()=> dispatch({type: 'increment'})}>+{ state.count }</button>
    <button onClick={()=> dispatch({type: 'decrement'})}>-{ state.count }</button>
   </>
  )
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值